A book library API created using an Express.js app connected via Sequelize to a PostgreSQL database in a Docker container.
Following on from the music library project (https://github.com/cocomarine/music-library), this project involves creating an Express API that stores information about readers, books, genres and authors. Users can create accounts ('readers') and list books ('books') with their genre ('genres') and author ('authors') information for browsing books. When a book is loaned or returned by a user, the book record is updated by adding or removing the user's ID ('ReaderId').
- Interpreting user stories and translating into app features
- Creating a web server using Express
- Handling HTTP requests and responses and errors
- Creating API using CRUD (Create, Read, Update and Delete) operations on databases
- Routing, middleware and controller functions
- Database synchronisation, manipuation and validation using Sequelize, a promise-based Node.js ORM (Object-Relational Mapping) tool
- Establishing complex relationships between database tables
- Creating test and development PostgreSQL databases in a Docker container
- Interacting with database using node-postgres, a collection of node.js modules
- Use of helpers and refractoring to make code DRY
- Using Postman to manage API requests
- Integration testing using Mocha, Chai and SuperTest
- Use of Dotenv to store sensitive information
- Use of Nodemon to automatically restart the node application when code changes
- Use of Swagger to generate API documentation
- Start by running postgres in a Docker container.
docker run --name postgres -p 5432:5432 -e POSTGRES_PASSWORD=password -d postgres
-
Make sure pgAdmin and Postman are installed.
-
Run pgAdmin and add new server with the following credentials to connect to the container-run postgres.
- hostname/address: localhost or the ip address of your postgres container
- user: postgres
- password: password
-
Create a fork of this repo. Then clone the repo and install project dependencies.
git clone [email protected]:[your-github-username]/book-library-api # to clone your copy of the repo
npm install # to download dependencies defined in the package.json file
- Create a .env file in the root of your project. This contains environment variables that Dotenv loads into process.env in the create-database.js file.
PGPASSWORD=password
PGDATABASE=book_library_dev
PGUSER=postgres
PGHOST=localhost
PGPORT=5433
-
Also, create a .env.test file to be used for creating test database by copying the same environment variables as .env but with different database name such as 'book_library_test'.
-
Add .env and .env.test to .gitignore to prevent your credentials from commited to Github.
-
To test or run the app, run the following commands.
npm test # to test the codes
npm start # to start the app at http://localhost:4000
- Use Postman and pgAdmin to check if the CRUD operations are working. You can also access API documentation at http://localhost:4000/api-docs .
POST
/books
(add a new book)
Parameters Body content, required Optional None title [string], ISBN [string], AuthorId [integer], GenreId [integer] ReaderId [integer]
code description 201
successful operation 400
content element empty, null or not unique
GET
/books
(find all the books)
Parameters Body content None None
code description 200
successful operation 404
books not found
GET
/books/{id}
(find a book by ID)
Parameters Body content bookId
None
code description 200
successful operation 404
book not found
PATCH
/books/{id}
(update a book by ID)
Parameters Body content bookId
title [string], ISBN [string], AuthorId [integer], GenreId [integer] or ReaderId [integer]
code description 200
successful operation 404
book not found
DELETE
/books/{id}
(delete a book by ID)
Parameters Body content bookId
None
code description 204
successful operation 404
book not found
POST
/readers
(add a new reader)
Parameters Body content None name [string,], email [string, email format], password [string, more than 8 characters]
code description 201
successful operation 400
content element empty, null, not unique, not right format or not right length
GET
/readers
(find all the readers)
Parameters Body content None None
code description 200
successful operation 404
readers not found
GET
/readers/{id}
(find a reader by ID)
Parameters Body content readerId
None
code description 200
successful operation 404
reader not found
PATCH
/readers/{id}
(update a reader by ID)
Parameters Body content readerId
name [string,], email [string, email format] or password [string, more than 8 characters]
code description 200
successful operation 404
reader not found
DELETE
/readers/{id}
(delete a reader by ID)
Parameters Body content readerId
None
code description 204
successful operation 404
reader not found
POST
/authors
(add a new author)
Parameters Body content None author[string]
code description 201
successful operation 400
content element empty, null or not unique
GET
/authors
(find all the authors)
Parameters Body content None None
code description 200
successful operation 404
authors not found
GET
/authors/{id}
(find an author by ID)
Parameters Body content authorId
None
code description 200
successful operation 404
author not found
PATCH
/authors/{id}
(update an author by ID)
Parameters Body content authorId
author [string]
code description 200
successful operation 404
author not found
DELETE
/authors/{id}
(delete an author by ID)
Parameters Body content authorId
None
code description 204
successful operation 404
author not found
POST
/genres
(add a new genre)
Parameters Body content None genre[string]
code description 201
successful operation 400
content element empty, null or not unique
GET
/genres
(find all the genres)
Parameters Body content None None
code description 200
successful operation 404
genres not found
GET
/genres/{id}
(find a genre by ID)
Parameters Body content genreId
None
code description 200
successful operation 404
genre not found
PATCH
/genres/{id}
(update a genre by ID)
Parameters Body content genreId
author [string]
code description 200
successful operation 404
genre not found
DELETE
/genres/{id}
(delete a genre by ID)
Parameters Body content genreId
None
code description 204
successful operation 404
genre not found
Books
column data type id integer (PK) title string ReaderId integer (FK) GenreId integer (FK) AuthorID integer (FK) Reader Genre Author
Readers
column data type id integer (PK) name string string password string Books
Authors
column data type id integer (PK) author string Books
Genres
column data type id integer (PK) genre string Books
👤 HJ Kang
- GitHub @cocomarine
- LinkedIn @hj-kang07