- Overview
- Backend Design
- API Specification. (CRUD-ordered for Lists then Books)
POST /reading-lists
GET /
orGET /reading-lists
GET /reading-lists-info
PUT /reading-lists/:listID
DELETE /reading-lists/:listID
GET /reading-lists/:listID
PUT /reading-lists/:listID/books
GET /reading-lists/:listID/books/:bookISBN
PUT /reading-lists/:listID/books/:isbn
DELETE /reading-lists/:listID/books/:bookisbn
The App Allows you to perform CRUD operations on reading lists and also on books within each reading list.
- Easy Way: Frontend Web App is hosted Reading Lists Web App
- The Other Way: Backend API
- You can use postman or any library to call the Backend API Endpoints directly.
- The API is hosted at https://readinglists.onrender.com
- Backend
- Redis NoSQL Database.
- Express.js Node Backend Server.
- Supertest + Jest for Backend Testing.
- Backend CI/CD. Automatic test running and deployments upon commits to master.
- API Detailed Documentation.
- Frontend
- Responsive React Frontend (Tested for mobile & desktop).
- Axios for server calls and Open Library API calls for search, and book covers.
- Hosting
- Backend hosted at Onrender.
- Frontend hosted at Github Pages.
Not only are CRUD operations provided for books in a single list, the App supports list-level CRUD operations.
The API uses two JSON keys in Redis to store the reading lists and their information:
-
ReadingLists
: This key contains an object with the list IDs as keys and the list objects as values. Each list object has the following properties:listName
: The name of the list.books
: An object with the book ISBNs as keys and the book objects as values. Each book object has the following properties:isbn
: The ISBN of the book.title
: The title of the book.author
: The author of the book.status
: The reading status of the book. It can be one of the following values:Unread
,In Progress
, orFinished
.image
: optional value set by a default if not provided on create.
-
ListsInfo
: This key contains an object with the list IDs as keys and the list information objects as values. Each list information object has the following property:listName
: The name of the list.
The JSON values can be manipulated and read without (reading -> parsing -> modifying -> reserializing -> writing back).
This allows for super efficient CRUD at both list- and book- level.
This endpoint creates a new reading list with a given name and returns the list ID and name.
The request body must contain a JSON object with the following property:
listName
: The name of the list.
The response body contains a JSON object with the following properties:
listID
: The ID of the created list.listName
: The name of the created list.
201
: The list was created successfully.400
: The list name was not provided or was invalid.500
: An internal server error occurred.
curl -X POST -H "Content-Type: application/json" -d "{\"listName\": \"My Reading List\"}" https://readinglists.onrender.com/reading-lists
{
"listID": "6e2053c6-fca1-4d7f-975a-ca29c0e31663",
"listName": "My Reading List"
}
This endpoint returns all the reading lists and their books.
No parameters are required.
The response body contains a JSON object with the list IDs as keys and the list objects as values.
200
: The lists were retrieved successfully.500
: An internal server error occurred.
curl -X GET https://readinglists.onrender.com/reading-lists
{
"6e2053c6-fca1-4d7f-975a-ca29c0e31663": {
"listName": "My Reading List",
"books": {
"9780143127550": {
"isbn": "9780143127550",
"title": "Sapiens: A Brief History of Humankind",
"author": "Yuval Noah Harari",
"status": "In Progress"
},
"9780062316097": {
"isbn": "9780062316097",
"title": "The Martian",
"author": "Andy Weir",
"status": "Unread"
}
}
}
}
This endpoint returns the information of all the reading lists.
No parameters are required.
The response body contains a JSON object with the list IDs as keys and the list information objects as values.
200
: The list information was retrieved successfully.500
: An internal server error occurred.
curl -X GET https://readinglists.onrender.com/reading-lists-info
{
"6e2053c6-fca1-4d7f-975a-ca29c0e31663": {
"listName": "My Reading List"
}
}
This endpoint updates the name of a specific reading list by its ID and returns the updated list ID and name.
The request must include the list ID as a path parameter and a JSON object with the following property in the body:
listName
: The new name of the list.
The response body contains a JSON object with the following properties:
listID
: The ID of the updated list.listName
: The name of the updated list.
200
: The list was updated successfully.400
: The list name was not provided or was invalid.404
: The list was not found.500
: An internal server error occurred.
curl -X PUT -H "Content-Type: application/json" -d "{\"listName\": \"Edited List Name\"}" https://readinglists.onrender.com/reading-lists/6e2053c6-fca1-4d7f-975a-ca29c0e31663
{
"listID": "6e2053c6-fca1-4d7f-975a-ca29c0e31663",
"listName": "Edited List Name"
}
This endpoint deletes a specific reading list and its books by its ID and returns a confirmation message.
The request must include the list ID as a path parameter.
The response body contains a json object with a message with the deleted list ID.
204
: The list was deleted successfully.404
: The list was not found.500
: An internal server error occurred.
curl -X DELETE https://readinglists.onrender.com/reading-lists/66634122-09dd-4ed8-9b14-8483ca06b178
{
"message": "deleted 66634122-09dd-4ed8-9b14-8483ca06b178"
}
This endpoint returns a specific reading list and its books by its ID.
The request must include the list ID as a path parameter.
The response body contains a JSON object with the following properties:
listName
: The name of the list.books
: An object with the book ISBNs as keys and the book objects as values.
200
: The list was retrieved successfully.404
: The list was not found.500
: An internal server error occurred.
curl -X GET https://readinglists.onrender.com/reading-lists/6e2053c6-fca1-4d7f-975a-ca29c0e31663
{
"listName": "My Reading List",
"books": {
"9780143127550": {
"isbn": "9780143127550",
"title": "Sapiens: A Brief History of Humankind",
"author": "Yuval Noah Harari",
"status": "In Progress"
},
"9780062316097": {
"isbn": "9780062316097",
"title": "The Martian",
"author": "Andy Weir",
"status": "Unread"
}
}
}
This endpoint adds a book to a specific reading list by its ID.
The request must include the list ID as a path parameter and a JSON object with the following property in the body:
book
: The book object to be added. It must have the following properties:isbn
: The ISBN of the book.title
: The title of the book.author
: The author of the book.status
: The reading status of the book. It must be one of the following values:Unread
,In Progress
, orFinished
.image
: The cover image of the book. (Optional. There is a default if not provided).
The response body contains a json object with a message with the added book title, ISBN, and list ID.
201
: The book was added successfully.400
: The book was not provided or was invalid.404
: The book already exists or the reading list does not exist.500
: An internal server error occurred.
curl -X POST -H "Content-Type: application/json" -d "{\"book\": {\"isbn\": \"9780062316097\", \"title\": \"The Martian\", \"author\": \"Andy Weir\", \"status\": \"Unread\"}}" https://readinglists.onrender.com/reading-lists/6e2053c6-fca1-4d7f-975a-ca29c0e31663/books
{
"message": "Added Book The Martian with ISBN: 9780062316097 to list 6e2053c6-fca1-4d7f-975a-ca29c0e31663"
}
This endpoint returns a specific book from a specific reading list by its ID and ISBN.
The request must include the list ID and the book ISBN as path parameters.
The response body contains a JSON object with the following properties:
isbn
: The ISBN of the book.title
: The title of the book.author
: The author of the book.status
: The reading status of the book.image
: The cover image of the book.
200
: The book was retrieved successfully.404
: The book or the list was not found.500
: An internal server error occurred.
curl -X GET https://readinglists.onrender.com/reading-lists/6e2053c6-fca1-4d7f-975a-ca29c0e31663/books/9780062316097
{
"isbn": "9780062316097",
"title": "The Martian",
"author": "Andy Weir",
"status": "Unread"
}
This endpoint updates a specific book from a specific reading list by its ID and ISBN and returns a confirmation message.
The request must include the list ID and the book ISBN as path parameters and a JSON object with the following property in the body:
book
: The book object to be updated. It must have the following properties:isbn
: The ISBN of the book.title
: The title of the book.author
: The author of the book.status
: The reading status of the book. It must be one of the following values:Unread
,In Progress
, orFinished
.
The response body contains a json object with a message with the updated book ISBN.
201
: The book was updated successfully.400
: The book was not provided or was invalid.404
: The book or the list does not exist.500
: An internal server error occurred.
curl -X PUT -H "Content-Type: application/json" -d "{\"book\": {\"isbn\": \"9780062316097\", \"title\": \"The Martian\", \"author\": \"Andy Weir\", \"status\": \"Finished\"}}" https://readinglists.onrender.com/reading-lists/6e2053c6-fca1-4d7f-975a-ca29c0e31663/books/9780062316097
{
"message": "Updated Books 9780062316097"
}
This endpoint deletes a specific book from a specific reading list by its ID and ISBN and returns a confirmation message.
The request must include the list ID and the book ISBN as path parameters.
The response body contains a json object with a message with the deleted list ID.
204
: The book was deleted successfully.404
: The book or the list was not found.500
: An internal server error occurred.
curl -X DELETE https://readinglists.onrender.com/reading-lists/6e2053c6-fca1-4d7f-975a-ca29c0e31663/books/9780062316097
{
"message": "deleted 6e2053c6-fca1-4d7f-975a-ca29c0e31663"
}