Book List

GET /books

Response:
        
          [
            {
              title: "…",
              subtitle: "…",
              isbn: "…",
              abstract: "…",
              numPages: 123,
              author: "…",
              publisher: "…",
              price: "$..",
              cover: "http://….png"
            },
            …
          ]
        
      

Book Detail

GET /books/:isbn

Response:
        
          {
            title: "…",
            subtitle: "…",
            isbn: "…",
            abstract: "…",
            numPages: 123,
            author: "…",
            publisher: "…",
            price: "$..",
            cover: "http://….png"
          }
        
      

Book Create

POST /books

Include a Content-Type: application/json header to use the JSON in the request body. Otherwise it will return a 2XX status code, but without changes being made to the data.

Title and ISBN are required fields.

Payload:
            
              {
                title: "…",
                subtitle: "…",
                isbn: "…",
                abstract: "…",
                numPages: 123,
                author: "…",
                publisher: "…",
                price: "$..",
                cover: "http://….png"
              }
            
          
Response:
            
              {
                title: "…",
                subtitle: "…",
                isbn: "…",
                abstract: "…",
                numPages: 123,
                author: "…",
                publisher: "…",
                price: "$..",
                cover: "http://….png"
              }
            
          
Error Response

400 Status Code

        
          {
            "errors": {
              "isbn": {
                "msg": "Es muss eine ISBN angegeben werden.",
                "param": "isbn",
                "location": "body"
              },
              "title": {
                "msg": "Es muss ein Titel angegeben werden.",
                "param": "title",
                "location": "body"
              }
            }
          }
        
      

Book Update

PUT /books/:isbn

Include a Content-Type: application/json header to use the JSON in the request body. Otherwise it will return a 2XX status code, but without changes being made to the data.

Title and ISBN are required fields.

Payload:
            
              {
                title: "…",
                subtitle: "…",
                isbn: "…",
                abstract: "…",
                numPages: 123,
                author: "…",
                publisher: "…",
                price: "$..",
                cover: "http://….png"
              }
            
          
Response:
            
              {
                title: "…",
                subtitle: "…",
                isbn: "…",
                abstract: "…",
                numPages: 123,
                author: "…",
                publisher: "…",
                price: "$..",
                cover: "http://….png"
              }
            
          
Error Response

400 Status Code

        
          {
            "errors": {
              "isbn": {
                "msg": "Es muss eine ISBN angegeben werden.",
                "param": "isbn",
                "location": "body"
              },
              "title": {
                "msg": "Es muss ein Titel angegeben werden.",
                "param": "title",
                "location": "body"
              }
            }
          }
        
      

Book Delete

DELETE /books/:isbn

Response:
        
          Ok
        
      

Operations

Pagination

GET /books?_page=2&_limit=10

Use _page and optionally _limit to paginate returned data. 10 items are returned by default

In the Link header you'll get first, prev, next and last links.

Response:
        
          [
            {
              title: "…",
              subtitle: "…",
              isbn: "…",
              abstract: "…",
              numPages: 123,
              author: "…",
              publisher: "…",
              price: "$..",
              cover: "http://….png"
            },
            …
          ]
        
      

Sort

GET /books?_sort=title&_order=desc

Add _sort and _order (ascending order by default)

Use a comma-separated list for multiple fields.

Response:
        
          [
            {
              title: "…",
              subtitle: "…",
              isbn: "…",
              abstract: "…",
              numPages: 123,
              author: "…",
              publisher: "…",
              price: "$..",
              cover: "http://….png"
            },
            …
          ]
        
      

Slice

GET /books?_start=10&_end=20

Add _start and _end or _limit (an X-Total-Count header is included in the response)

Works exactly as Array.slice (i.e. _start is inclusive and _end exclusive)

Response:
        
          [
            {
              title: "…",
              subtitle: "…",
              isbn: "…",
              abstract: "…",
              numPages: 123,
              author: "…",
              publisher: "…",
              price: "$..",
              cover: "http://….png"
            },
            …
          ]
        
      

Operators

GET /books?numPages_gte=100&numPages_lte=500

Add _gte or _lte for getting a range

Add _ne to exclude a value

Add _like to filter (RegExp supported)

Response:
        
          [
            {
              title: "…",
              subtitle: "…",
              isbn: "…",
              abstract: "…",
              numPages: 123,
              author: "…",
              publisher: "…",
              price: "$..",
              cover: "http://….png"
            },
            …
          ]
        
      

GET /books?q=vue

Add q for a full-text search

Response:
        
          [
            {
              title: "…",
              subtitle: "…",
              isbn: "…",
              abstract: "…",
              numPages: 123,
              author: "…",
              publisher: "…",
              price: "$..",
              cover: "http://….png"
            },
            …
          ]
        
      

Authentication

Register

POST /register

The response contains the JWT access token (expiration time of 1 hour). The access token has the following claims:

Payload:
            
              {
                email: "youremail@demo.com",
                password: "bestPassw0rd",
              }
            
          
Response:
            
              {
                accessToken: "xxx.xxx.xxx",
                user: {
                  email: "email@domain.com",
                  password: "HASH",
                  id: 1
                }
              }
            
          
Other propreties

Any other property can be added to the request body without being validated

        
          {
            email: "youremail@demo.com",
            password: "bestPassw0rd",
            firstname: "Max",
            lastname: "Mustermann",
            age: 101
          }
        
      

Login

POST /login

The response contains the JWT access token (expiration time of 1 hour). The access token has the following claims:

Payload:
            
              {
                email: "youremail@demo.com",
                password: "bestPassw0rd",
              }
            
          
Response:
            
              {
                accessToken: "xxx.xxx.xxx",
                user: {
                  email: "email@domain.com",
                  password: "HASH",
                  id: 1
                }
              }
            
          

User Update

Any update to an existing user (via PATCH or PUT methods) will go through the same process for email and password.

PUT /users/:id
PATCH /users/:id

Admin User - Login Data

There is already a demo user inserted into the database. The credentials to login as this admin user are as follows:

User Relation

A book can be linked to a specific user by sending the userId parameter when adding a book via POST.

Payload:
            
              {
                title: "…",
                subtitle: "…",
                isbn: "…",
                abstract: "…",
                numPages: 123,
                author: "…",
                publisher: "…",
                price: "$..",
                cover: "http://….png",
                userId: "1"
              }
            
          
Response:
            
              {
                title: "…",
                subtitle: "…",
                isbn: "…",
                abstract: "…",
                numPages: 123,
                author: "…",
                publisher: "…",
                price: "$..",
                cover: "http://….png",
                userId: "1"
              }
            
          

Relational Request

You can retrieve a book list for a specific user with the nested book route.

PUT /users/:id/books

Guarded Routes

Guarded routes exist at the root and can restrict access to any resource you put after them:

Route Resource permissions
/664/* User must be logged to write the resource.
Everyone can read the resource.
/660/* User must be logged to write and read the resource.
/644/* User must own the resource to write the resource.
Everyone can read the resource.
/640/* User must own the resource to write the resource.
User must be logged to read the resource.
/600/* User must own the resource to write or read the resource.
/444/* No one can write the resource.
Everyone can read the resource.
/440/* No one can write the resource.
User must be logged to read the resource.
/400/* No one can write the resource.
User must own the resource to read the resource.

Examples:

Public user (not logged-in) does the following requests:

Request Response
GET /664/books 200 OK
POST /664/books
{isbn: '123123123'}
401 UNAUTHORIZED

Logged-in user with id: 1 does the following requests:

Request Response
GET /600/users/1
Authorization: Bearer xxx.xxx.xxx
200 OK
GET /600/users/42
Authorization: Bearer xxx.xxx.xxx
403 FORBIDDEN