GoBookAPI is a sample RESTful JSON API written in Go, designed to manage books, provide user authentication/authorization using tokens, and execute various operations including adding, deleting, viewing, and updating books. The API utilizes a PostgreSQL database for data storage and retrieval.
-
System Monitoring:
- Logging
- Metrics
- Alerts
- Healthcheck
- Tracing
- Error Handling
-
Security:
- CORS avoidance
- IP-based rate limiting
-
Authentication/Authorization:
- Stateful token-based approach for secure authentication and authorization
-
Data Management:
- Book addition
- Book deletion
- Book updating
- Partial data updates
- Book retrieval
- Parsing and validating query string parameters
- Listing data
- Filtering and full-text search
- Sorting and paginating
- Returning pagination metadata
- Optimistic concurrency control
-
Other:
- Continuous integration (CI)
- Docker (Containerization)
GoBookAPI
├── Dockerfile
├── Makefile
├── README.md
├── cmd
│ └── api
│ ├── books.go
│ ├── context.go
│ ├── errors.go
│ ├── healthcheck.go
│ ├── helpers.go
│ ├── main.go
│ ├── middleware.go
│ ├── routes.go
│ ├── server.go
│ ├── tokens.go
│ └── users.go
├── docker-compose.yaml
├── go.mod
├── go.sum
├── internal
│ ├── data
│ │ ├── books.go
│ │ ├── filters.go
│ │ ├── models.go
│ │ ├── pages.go
│ │ ├── tokens.go
│ │ └── users.go
│ ├── jsonlog
│ │ └── jsonlog.go
│ └── validator
│ └── validator.go
└── migrations
├── 000001_create_books_table.down.sql
├── 000001_create_books_table.up.sql
├── 000002_add_books_check_constraints.down.sql
├── 000002_add_books_check_constraints.up.sql
├── 000003_add_books_indexes.down.sql
├── 000003_add_books_indexes.up.sql
├── 000004_create_users_table.down.sql
├── 000004_create_users_table.up.sql
├── 000005_create_tokens_table.down.sql
└── 000005_create_tokens_table.up.sql
There are two options:
- You can run the project without docker.
- You can run the project with docker.
- Go
- PostgreSQL
- make
- go-migrate
- git
- Code Editor
- First, clone the repository:
git clone https://github.com/barantoraman/GoBookAPI.git
- Move into the directory:
cd GoBookAPI
- Create a PostgreSQL database with a named gobookapi.
- Create a POSTGRESQL superuser with named gobookapi.
- Set the password.
- Create the environment variables for databases:
export DB_DSN=YOUR_DATABASE_USER:YOUR_USER_PASS@/YOUR_DATABASE_NAME
-
Edit the specified field in the Makefile that is related to the data source name, as per your requirement.
-
Run the project:
make setup
- 🎉 Now you can test the endpoints as demonstrated in the Usage Examples section. 🎉
- First, clone the repository:
git clone https://github.com/barantoraman/GoBookAPI.git
- Move into the directory:
cd GoBookAPI
- Build the containers using the configuration in docker-compose.yaml:
make docker/build
- Start the containers using the configuration in docker-compose.yaml:
make docker/run
- Stop the containers:
make docker/stop
- Healthcheck:
- Endpoint to perform a health check and ensure the application is running smoothly.
curl localhost:4000/v1/healthcheck
- Metrics:
- Endpoint to retrieve application metrics for monitoring and analysis.
curl localhost:4000/debug/vars
- Signup:
- If you wish to use the other functionalities of the application and test its additional endpoints, you need to sign up. Otherwise, you'll receive a (HTTP) 401 Unauthorized response.
curl -d '{
"name": "Eliza Thornberry",
"email": "ethornberry@example.com",
"password": "random-password123"
}' localhost:4000/v1/users
- Login:
curl -d '{
"email": "ethornberry@example.com",
"password": "random-password123"
}' localhost:4000/v1/tokens/authentication
- Add a Book:
curl -d '{
"isbn": "0000000000001",
"title": "Book1",
"author": "Author1",
"genres": ["genre1", "genre2", "genre3"],
"pages": "100 pages",
"language": "English",
"publisher": "Publisher 1",
"year": 1900
}' -H "Authorization: Bearer UPXA2GVIOIE6KWUWDTT5NG4SH4" \
"localhost:4000/v1/books"
- Update a Book:
- Update all details of the book in the database.
curl -X PATCH -d '{
"isbn": "0000000000001",
"title": "Book1",
"author": "Author1",
"genres": ["genre1", "genre2", "genre3"],
"pages": "100 pages",
"language": "English",
"publisher": "Publisher 1",
"year": 1966
}' -H "Authorization: Bearer UPXA2GVIOIE6KWUWDTT5NG4SH4" \
"localhost:4000/v1/books/1"
- Partial Update: -Updating specific fields of the book's information.
curl -X PATCH -d '{
"year": 1902
}' -H "Authorization: Bearer UPXA2GVIOIE6KWUWDTT5NG4SH4" \
"localhost:4000/v1/books/1"
- Delete a Book by id:
curl -H "Authorization: Bearer UPXA2GVIOIE6KWUWDTT5NG4SH4" \
-X DELETE "localhost:4000/v1/books/4"
- Get All Book:
curl -H "Authorization: Bearer UPXA2GVIOIE6KWUWDTT5NG4SH4" \
"localhost:4000/v1/books"
- Get All Book:
- For example, in this scenario, there will be a single results page with 2 results on that page.
curl -H "Authorization: Bearer UPXA2GVIOIE6KWUWDTT5NG4SH4" \
"localhost:4000/v1/books?cursor=1&cursor_size=2"
- Searching example:
- Searching for the desired book based on its features(Title + Author).
curl -H "Authorization: Bearer UPXA2GVIOIE6KWUWDTT5NG4SH4" \
"localhost:4000/v1/books?title=Book1&author=Author1"
- Searching example:
- Searching for the desired book based on its features(Title).
curl -H "Authorization: Bearer UPXA2GVIOIE6KWUWDTT5NG4SH4" \
"localhost:4000/v1/books?title=Book1"
- Searching example:
- Searching for the desired book based on its features(ISBN + Title + Author).
curl -H "Authorization: Bearer UPXA2GVIOIE6KWUWDTT5NG4SH4" \
"localhost:4000/v1/books?isbn=0000000000001&title=Book1&author=Author1"
- Searching example:
- Searching for the desired book based on its features(ISBN).
curl -H "Authorization: Bearer UPXA2GVIOIE6KWUWDTT5NG4SH4" \
"localhost:4000/v1/books?isbn=0000000000001"
- Searching example:
- Searching for the desired book based on its features(Genres).
curl -H "Authorization: Bearer UPXA2GVIOIE6KWUWDTT5NG4SH4" \
"localhost:4000/v1/books?genres=genre1"
- Searching example:
- Searching for the desired book based on its features(Title).
curl -H "Authorization: Bearer UPXA2GVIOIE6KWUWDTT5NG4SH4" \
"localhost:4000/v1/books?title=new+book"
- Full Text Search (enough to contain the word):
curl -H "Authorization: Bearer UPXA2GVIOIE6KWUWDTT5NG4SH4" \
"localhost:4000/v1/books?title=new"
- Sort by ID (ASC):
curl -H "Authorization: Bearer UPXA2GVIOIE6KWUWDTT5NG4SH4" \
"localhost:4000/v1/books?sort=id"
- Sort by ID (DESC):
curl -H "Authorization: Bearer UPXA2GVIOIE6KWUWDTT5NG4SH4" \
"localhost:4000/v1/books?sort=-id"
- Sort by Title (ASC):
curl -H "Authorization: Bearer UPXA2GVIOIE6KWUWDTT5NG4SH4" \
"localhost:4000/v1/books?sort=title"
- Sort by Title (DESC):
curl -H "Authorization: Bearer UPXA2GVIOIE6KWUWDTT5NG4SH4" \
"localhost:4000/v1/books?sort=-title"
- Sort by Year (ASC):
curl -H "Authorization: Bearer UPXA2GVIOIE6KWUWDTT5NG4SH4" \
"localhost:4000/v1/books?sort=year"
- Sort by Year (DESC):
curl -H "Authorization: Bearer UPXA2GVIOIE6KWUWDTT5NG4SH4" \
"localhost:4000/v1/books?sort=-year"
- Sort by Author (ASC):
curl -H "Authorization: Bearer UPXA2GVIOIE6KWUWDTT5NG4SH4" \
"localhost:4000/v1/books?sort=author"
- Sort by Author (DESC):
curl -H "Authorization: Bearer UPXA2GVIOIE6KWUWDTT5NG4SH4" \
"localhost:4000/v1/books?sort=-author"