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.
{
title: "…",
subtitle: "…",
isbn: "…",
abstract: "…",
numPages: 123,
author: "…",
publisher: "…",
price: "$..",
cover: "http://….png"
}
{
title: "…",
subtitle: "…",
isbn: "…",
abstract: "…",
numPages: 123,
author: "…",
publisher: "…",
price: "$..",
cover: "http://….png"
}
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.
{
title: "…",
subtitle: "…",
isbn: "…",
abstract: "…",
numPages: 123,
author: "…",
publisher: "…",
price: "$..",
cover: "http://….png"
}
{
title: "…",
subtitle: "…",
isbn: "…",
abstract: "…",
numPages: 123,
author: "…",
publisher: "…",
price: "$..",
cover: "http://….png"
}
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
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.
[
{
title: "…",
subtitle: "…",
isbn: "…",
abstract: "…",
numPages: 123,
author: "…",
publisher: "…",
price: "$..",
cover: "http://….png"
},
…
]
Sort
GET /books?_sort=title&_order=desc
Add _sort and
Use a comma-separated list for multiple fields.
Response:
[
{
title: "…",
subtitle: "…",
isbn: "…",
abstract: "…",
numPages: 123,
author: "…",
publisher: "…",
price: "$..",
cover: "http://….png"
},
…
]
Slice
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)
[
{
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)
[
{
title: "…",
subtitle: "…",
isbn: "…",
abstract: "…",
numPages: 123,
author: "…",
publisher: "…",
price: "$..",
cover: "http://….png"
},
…
]
Full-text search
GET /books?q=vue
Add q for a full-text search
[
{
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:
sub:the user id.email:the user email.
{
email: "youremail@demo.com",
password: "bestPassw0rd",
}
{
accessToken: "xxx.xxx.xxx",
user: {
email: "email@domain.com",
password: "HASH",
id: 1
}
}
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:
sub:the user id.email:the user email.
{
email: "youremail@demo.com",
password: "bestPassw0rd",
}
{
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:
admin@bookmonkey.apipassword1!
User Relation
A book can be linked to a specific user by sending the userId parameter when adding a book via POST.
{
title: "…",
subtitle: "…",
isbn: "…",
abstract: "…",
numPages: 123,
author: "…",
publisher: "…",
price: "$..",
cover: "http://….png",
userId: "1"
}
{
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/1Authorization: Bearer xxx.xxx.xxx |
200 OK |
GET /600/users/42Authorization: Bearer xxx.xxx.xxx |
403 FORBIDDEN |