An open API service indexing awesome lists of open source software.

https://github.com/winterrdog/odin-blog-api

An exercise by The Odin Project( TOP ) to create a blog. It has both a front & back end
https://github.com/winterrdog/odin-blog-api

blog blogging js micro-blog typescript

Last synced: 6 months ago
JSON representation

An exercise by The Odin Project( TOP ) to create a blog. It has both a front & back end

Awesome Lists containing this project

README

          

# odin-blog-api

An exercise by The Odin Project( TOP ) to create a blog. I only designed the backend as that's my speciality :), then [_@muchubatactics_](https://github.com/muchubatactics) did the frontend. The backend is a `REST`ful API built with `Node.js`, `React`( for the frontend ), `Express.js`, `MongoDB`, and `JWT` for authorization. It has `16+` endpoints for creating, reading, updating, and deleting users, posts, comments, and replies.

**AUTHORS**: [_muchubatactics_](https://github.com/muchubatactics) & [_winterrdog_](https://github.com/winterrdog)

## REQUIREMENTS

Make sure you have the following installed:

- `Postman` / `curl` - _for testing the API_
- `Docker` - _for building the database(`mongodb`) and the application_
- `Docker Compose` - _for deploying the application_. Use the new Go-based version, `docker compose` instead of the old Python-based version, `docker-compose` otherwise you will get an error unless you use some workarounds.

## RUNNING BACKEND

- To set up the environment variables, create a `.env` file in the root directory and copy the contents of `.env.example` into it. Then fill in the missing values.

- To run the backend, run the following command:

```bash
cd ./src
./containerize.sh
```

- Stop the backend by running the following command:

```bash
docker compose down
```

- In case you wanna run backend in production mode, run the following command:

```bash
cd ./src
docker compose -f docker-compose.yml up
```

Remember to set `MONGODB_URI` to your production database URI somewhere in the cloud in the `.env` file.

- The backend will be available at `http://localhost:3000`.

## VIEWING THE LOGS

- To view logs, run the following command:

```bash
docker logs --tail=300 -f blog_backend
```

- The container will also write logs to `./src/blog-app.log` external to the container.

## API DOCUMENTATION

This backend has 3 features:

- `Authentication` - _for creating, deleting, updating and logging in users_
- `Posts` - _for creating, reading, updating and deleting posts_
- `Comments` - _for creating, reading, updating and deleting comments_

It has `16+` endpoints i.e.:

### User Endpoints

- `POST /api/v1/users/sign-up` - _for registering a user_
- `POST /api/v1/users/sign-in` - _for logging in a user_
- `PATCH /api/v1/users/update` - _for updating a user details_
- `DELETE /api/v1/users/delete` - _for deleting a user_
- `PATCH /api/v1/users/log-out` - _for logging out a user_

### Post Endpoints

- `POST /api/v1/posts/` - _for creating a post_
- `GET /api/v1/posts/user-posts` - _for getting a user's posts_
- `GET /api/v1/posts/liked-posts` - _for getting a user's liked posts_
- `GET /api/v1/posts/recently-viewed` - _for getting a user's 5 most recently viewed posts_
- `GET /api/v1/posts/` - _for getting all posts_
- `GET /api/v1/posts/:postId` - _for getting a post_
- `PATCH /api/v1/posts/:postId` - _for updating a post_
- `DELETE /api/v1/posts/:postId` - _for deleting a post_
- `PATCH /api/v1/posts/:postId/likes` - _for adding a like_
- `PATCH /api/v1/posts/:postId/dislikes` - _for adding a dislike_

### Comment Endpoints

- `POST /api/v1/post-comments/:postId/comments/` - _for creating a comment_
- `GET /api/v1/post-comments/:postId/comments/` - _for getting all comments for a post_
- `GET /api/v1/post-comments/:postId/comments/:commentId` - _for getting a comment_
- `GET /api/v1/post-comments/user-comments` - _for getting a user's comments_
- `GET /api/v1/post-comments/user-liked-comments` - _for getting a user's liked comments_
- `PATCH /api/v1/post-comments/:postId/comments/:commentId` - _for updating a comment_
- `DELETE /api/v1/post-comments/:postId/comments/:commentId` - _for deleting a comment_
- `PATCH /api/v1/post-comments/:postId/comments/:commentId/likes` - _for adding a like_
- `DELETE /api/v1/post-comments/:postId/comments/:commentId/likes` - _for removing a like_
- `PATCH /api/v1/post-comments/:postId/comments/:commentId/dislikes` - _for adding a dislike_
- `DELETE /api/v1/post-comments/:postId/comments/:commentId/dislikes` - _for removing a dislike_
- `POST /api/v1/post-comments/:postId/comments/:commentId/replies` - _for creating a reply_
- `PATCH /api/v1/post-comments/:postId/comments/:commentId/replies` - _for adding a reply_
- `DELETE /api/v1/post-comments/:postId/comments/:commentId/replies/:replyId` - _for deleting a reply_

### AUTHENTICATION

- The API uses `JWT` for authentication. The JWT is required in the `Authorization` header for **all** requests except for `sign-up` and `sign-in` requests and for user actions that only require reading data from the server i.e `GET` requests.

## SAMPLE REQUESTS

- To test the API, you can use `Postman` or `curl`. Below are some sample requests:

### User Requests

#### Sign up a user

```sh
curl -X POST -H "Content-Type: application/json" -d '{
"name": "John Doe",
"pass": "password",
"role": "author"
}' http://localhost:3000/api/v1/users/sign-up
```

The server will respond with:

```json
HTTP/1.1 201 Created

{
"message": "User created successfully",
"token": "eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InN1YiI6IjY2MjY1NWMxYTJlMjkxYjg0NjM1ODlmZSIsInJvbGUiOiJhdXRob3IifSwiaWF0IjoxNzEzNzg4MzUzLCJleHAiOjE3MTM5NjExNTN9.8oc3DOAR6SqaWUBynMZlAvHJr202cTXbtiq80EVyO5RSXMJrdGJ-aWdZF_lfR1p4"
}
```

#### Sign in a user

```sh
curl -X POST -H "Content-Type: application/json" -d '{"name": "John Doe", "pass": "password"}' http://localhost:3000/api/v1/users/sign-in
```

The server will respond with:

```json
HTTP/1.1 200 OK

{
"message": "User signed in successfully",
"token": "eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InN1YiI6IjY2MjY1NWMxYTJlMjkxYjg0NjM1ODlmZSIsInJvbGUiOiJhdXRob3IifSwiaWF0IjoxNzEzNzg4MzUzLCJleHAiOjE3MTM5NjExNTN9.8oc3DOAR6SqaWUBynMZlAvHJr202cTXbtiq80EVyO5RSXMJrdGJ-aWdZF_lfR1p4"
}
```

#### Update a user's details

```sh
curl -X PATCH -H "Content-Type: application/json" -d '{"name": "Jane Doe", "role": "reader"}' http://localhost:3000/api/v1/users/update
```

The server will respond with:

```json
HTTP/1.1 200 OK

{
"message": "User updated",
"user": {
"name": "Jane Doe",
"role": "reader",
"id": "6623cfc033d53b054fe9b0c3",
"dateCreated": "2024-04-20T14:22:56.517Z",
"dateUpdated": "2024-04-22T12:29:46.406Z"
}
}
```

#### Delete a user

```sh
curl -X DELETE -H "Authorization: Bearer eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InN1YiI6IjY2MjY1NWMxYTJlMjkxYjg0NjM1ODlmZSIsInJvbGUiOiJhdXRob3IifSwiaWF0IjoxNzEzNzg4MzUzLCJleHAiOjE3MTM5NjExNTN9.8oc3DOAR6SqaWUBynMZlAvHJr202cTXbtiq80EVyO5RSXMJrdGJ-aWdZF_lfR1p4" http://localhost:3000/api/v1/users/delete
```

The server will respond with:

```json
HTTP/1.1 204 No Content
```

#### Log out a user

```sh
curl -X PATCH -H "Authorization: Bearer eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InN1YiI6IjY2MjY1NWMxYTJlMjkxYjg0NjM1ODlmZSIsInJvbGUiOiJhdXRob3IifSwiaWF0IjoxNzEzNzg4MzUzLCJleHAiOjE3MTM5NjExNTN9.8oc3DOAR6SqaWUBynMZlAvHJr202cTXbtiq80EVyO5RSXMJrdGJ-aWdZF_lfR1p4" http://localhost:3000/api/v1/users/log-out
```

The server will respond with:

```json
HTTP/1.1 204 No Content

```

### Post Requests

#### Create a post.

Only registered users can create posts. The JWT is required in the Authorization header.

```sh
curl -X POST -H "Content-Type: application/json" -H "
Authorization: Bearer eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InN1YiI6IjY2MjY1NWMxYTJlMjkxYjg0NjM1ODlmZSIsInJvbGUiOiJhdXRob3IifSwiaWF0IjoxNzEzNzg4MzUzLCJleHAiOjE3MTM5NjExNTN9.8oc3DOAR6SqaWUBynMZlAvHJr202cTXbtiq80EVyO5RSXMJrdGJ-aWdZF_lfR1p4" -d '{
"title": "My first post",
"body": "This is my first post. I hope you like it."
}' http://localhost:3000/api/v1/posts/
```

The server will respond with:

```json
HTTP/1.1 201 Created

{
"message": "Post created successfully",
"post": {
"author": "John Doe",
"title": "My first post",
"body": "This is my first post. I hope you like it.",
"hidden": false,
"id": "662659aaa2e291b846358a06",
"dateCreated": "2024-04-22T12:35:54.030Z",
"dateUpdated": "2024-04-22T12:35:54.030Z"
}
}
```

#### Get all posts for a user

Make sure the JWT is in the Authorization header since we rely on it to get the user's posts.

```sh
curl -X GET
-H "Authorization: Bearer eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InN1YiI6IjY2MjY1NWMxYTJlMjkxYjg0NjM1ODlmZSIsInJvbGUiOiJhdXRob3IifSwiaWF0IjoxNzEzNzg4MzUzLCJleHAiOjE3MTM5NjExNTN9.8oc3DOAR6SqaWUBynMZlAvHJr202cTXbtiq80EVyO5RSXMJrdGJ-aWdZF_lfR1p4"
http://localhost:3000/api/v1/posts/user-posts
```

The server will respond with:

```json
HTTP/1.1 200 OK

{
"message": "User's posts retrieved successfully",
"posts": [
{
"author": "John Doe",
"title": "My first post",
"body": "This is my first post. I hope you like it.",
"hidden": false,
"id": "662659aaa2e291b846358a06",
"dateCreated": "2024-04-22T12:35:54.030Z",
"dateUpdated": "2024-04-22T12:35:54.030Z"
}
]
}
```

#### Get all liked posts for a user

Make sure the JWT is in the Authorization header since we rely on it to get the user's liked posts.

```sh
curl -X GET
-H "Authorization: Bearer eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InN1YiI6IjY2MjY1NWMxYTJlMjkxYjg0NjM1ODlmZSIsInJvbGUiOiJhdXRob3IifSwiaWF0IjoxNzEzNzg4MzUzLCJleHAiOjE3MTM5NjExNTN9.8oc3DOAR6SqaWUBynMZlAvHJr202cTXbtiq80EVyO5RSXMJrdGJ-aWdZF_lfR1p4"
http://localhost:3000/api/v1/posts/liked-posts
```

The server will respond with:

```json
HTTP/1.1 200 OK

{
"message": "User's liked posts retrieved successfully",
"posts": [
{
"author": "John Doe",
"title": "My first post",
"body": "This is my first post. I hope you like it.",
"hidden": false,
"id": "662659aaa2e291b846358a06",
"dateCreated": "2024-04-22T12:35:54.030Z",
"dateUpdated": "2024-04-22T12:35:54.030Z"
}
]
}
```

#### Get the 5 most recently viewed posts for a user

Make sure the JWT is in the Authorization header since we rely on it to get the user's recently viewed posts.

```sh
curl -X GET

-H "Authorization: Bearer eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InN1YiI6IjY2MjY1NWMxYTJlMjkxYjg0NjM1ODlmZSIsInJvbGUiOiJhdXRob3IifSwiaWF0IjoxNzEzNzg4MzUzLCJleHAiOjE3MTM5NjExNTN9.8oc3DOAR6SqaWUBynMZlAvHJr202cTXbtiq80EVyO5RSXMJrdGJ-aWdZF_lfR1p4"
http://localhost:3000/api/v1/posts/recently-viewed
```

The server will respond with:

```json
HTTP/1.1 200 OK

{
"message": "User's recently viewed posts retrieved successfully",
"posts": [
{
"author": "John Doe",
"title": "My first post",
"body": "This is my first post. I hope you like it.",
"hidden": false,
"id": "662659aaa2e291b846358a06",
"dateCreated": "2024-04-22T12:35:54.030Z",
"dateUpdated": "2024-04-22T12:35:54.030Z"
}
]
}
```

It will return a maximum of 5 posts. If the user has viewed less than 5 posts, it will return all the posts the user has viewed.

For the case when there's no post viewed by the user, the server will respond with a `404` status code and the following message:

```json
HTTP/1.1 404 Not Found

{
message: "no recently viewed posts found for user",
}
```

#### Get all posts

```sh
curl -X GET http://localhost:3000/api/v1/posts/
```

The server will respond with:

```json
HTTP/1.1 200 OK

{
"message": "Posts retrieved successfully",
"posts": [
{
"author": "John Doe",
"title": "My first post",
"body": "This is my first post. I hope you like it.",
"hidden": false,
"id": "662659aaa2e291b846358a06",
"dateCreated": "2024-04-22T12:35:54.030Z",
"dateUpdated": "2024-04-22T12:35:54.030Z"
},
{
"author": "Jane Doe",
"title": "My second post",
"body": "This is my second post. I hope you like it.",
"hidden": false,
"id": "662659aaa2e291b846358a07",
"dateCreated": "2024-04-22T12:35:54.030Z",
"dateUpdated": "2024-04-22T12:35:54.030Z"
}
]
}
```

#### Get a post

```sh
curl -X GET http://localhost:3000/api/v1/posts/662659aaa2e291b846358a06
```

The server will respond with:

```json
HTTP/1.1 200 OK

{
"message": "Post retrieved successfully",
"post": {
"author": "John Doe",
"title": "My first post",
"body": "This is my first post. I hope you like it.",
"hidden": false,
"id": "662659aaa2e291b846358a06",
"dateCreated": "2024-04-22T12:35:54.030Z",
"dateUpdated": "2024-04-22T12:35:54.030Z"
}
}
```

#### Update a post

```sh
curl -X PATCH -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InN1YiI6IjY2MjY1NWMxYTJlMjkxYjg0NjM1ODlmZSIsInJvbGUiOiJhdXRob3IifSwiaWF0IjoxNzEzNzg4MzUzLCJleHAiOjE3MTM5NjExNTN9.8oc3DOAR6SqaWUBynMZlAvHJr202cTXbtiq80EVyO5RSXMJrdGJ-aWdZF_lfR1p4" -d '{
"title": "My first post",
"body": "This is my first post. I hope you like it. I have updated it."
}' http://localhost:3000/api/v1/posts/662659aaa2e291b846358a06
```

The server will respond with:

```json
HTTP/1.1 200 OK

{
"message": "Post updated",
"post": {
"author": "John Doe",
"title": "My first post",
"body": "This is my first post. I hope you like it. I have updated it.",
"hidden": false,
"id": "662659aaa2e291b846358a06",
"dateCreated": "2024-04-22T12:35:54.030Z",
"dateUpdated": "2024-04-22T12:35:54.030Z"
}
}
```

#### Delete a post

```sh
curl -X DELETE -H "Authorization: Bearer eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InN1YiI6IjY2MjY1NWMxYTJlMjkxYjg0NjM1ODlmZSIsInJvbGUiOiJhdXRob3IifSwiaWF0IjoxNzEzNzg4MzUzLCJleHAiOjE3MTM5NjExNTN9.8oc3DOAR6SqaWUBynMZlAvHJr202cTXbtiq80EVyO5RSXMJrdGJ-aWdZF_lfR1p4" http://localhost:3000/api/v1/posts/662659aaa2e291b846358a06
```

The server will respond with:

```json
HTTP/1.1 204 No Content
```

### Comment Requests

#### Create a comment.

Only registered users can create comments. The JWT is required in the Authorization header.

```sh
curl -X POST -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InN1YiI6IjY2MjY1NWMxYTJlMjkxYjg0NjM1ODlmZSIsInJvbGUiOiJhdXRob3IifSwiaWF0IjoxNzEzNzg4MzUzLCJleHAiOjE3MTM5NjExNTN9.8oc3DOAR6SqaWUBynMZlAvHJr202cTXbtiq80EVyO5RSXMJrdGJ-aWdZF_lfR1p4" -d '{
"body": "This is a great post. I love it."
}' http://localhost:3000/api/v1/post-comments/662659aaa2e291b846358a07/comments/
```

The server will respond with:

```json
HTTP/1.1 201 Created

{
"message": "comment created successfully",
"comment": {
"body": "how does it work?",
"tldr": "work",
"user": "kaboom",
"post": "6623d00e33d53b054fe9b0c7",
"id": "66265bcda2e291b846358a17",
"dateCreated": "2024-04-22T12:45:01.875Z",
"dateUpdated": "2024-04-22T12:45:01.875Z"
}
}
```

#### Get all comments for a post

```sh
curl -X GET http://localhost:3000/api/v1/post-comments/662659aaa2e291b846358a07/comments/
```

The server will respond with:

```json
HTTP/1.1 200 OK

{
"message": "post comments fetched successfully",
"comments": [
{
"body": "This is a great post. I love it.",
"tldr": "great post",
"user": "John Doe",
"post": "662659aaa2e291b846358a07",
"id": "66265bcda2e291b846358a17",
"dateCreated": "2024-04-22T12:45:01.875Z",
"dateUpdated": "2024-04-22T12:45:01.875Z"
}
]
}
```

#### Get all comments for a user

Make sure the JWT is in the Authorization header since we rely on it to get the user's comments.

```sh
curl -X GET
-H "Authorization: Bearer eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InN1YiI6IjY2MjY1NWMxYTJlMjkxYjg0NjM1ODlmZSIsInJvbGUiOiJhdXRob3IifSwiaWF0IjoxNzEzNzg4MzUzLCJleHAiOjE3MTM5NjExNTN9.8oc3DOAR6SqaWUBynMZlAvHJr202cTXbtiq80EVyO5RSXMJrdGJ-aWdZF_lfR1p4"
http://localhost:3000/api/v1/post-comments/user-comments
```

The server will respond with:

```json
HTTP/1.1 200 OK

{
"message": "user comments fetched successfully",
"comments": [
{
"body": "This is a great post. I love it.",
"tldr": "great post",
"user": "John Doe",
"post": "662659aaa2e291b846358a07",
"id": "66265bcda2e291b846358a17",
"dateCreated": "2024-04-22T12:45:01.875Z",
"dateUpdated": "2024-04-22T12:45:01.875Z"
}
]
}
```

#### Get all liked comments for a user

Make sure the JWT is in the Authorization header since we rely on it to get the user's liked comments.

```sh
curl -X GET
-H "Authorization: Bearer eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InN1YiI6IjY2MjY1NWMxYTJlMjkxYjg0NjM1ODlmZSIsInJvbGUiOiJhdXRob3IifSwiaWF0IjoxNzEzNzg4MzUzLCJleHAiOjE3MTM5NjExNTN9.8oc3DOAR6SqaWUBynMZlAvHJr202cTXbtiq80EVyO5RSXMJrdGJ-aWdZF_lfR1p4"
http://localhost:3000/api/v1/post-comments/user-liked-comments
```

On success, the server will respond with:

```json
HTTP/1.1 200 OK

{
"message": "user liked comments fetched successfully",
"comments": [
{
"body": "This is a great post. I love it.",
"tldr": "great post",
"user": "John Doe",
"post": "662659aaa2e291b846358a07",
"id": "66265bcda2e291b846358a17",
"dateCreated": "2024-04-22T12:45:01.875Z",
"dateUpdated": "2024-04-22T12:45:01.875Z"
}
]
}
```

In case no liked comments are found, the server will respond with:

```json
HTTP/1.1 404 Not Found

{
"message": "no comments were liked by the user",
}
```

#### Get a comment

```sh
curl -X GET http://localhost:3000/api/v1/post-comments/662659aaa2e291b846358a07/comments/66265bcda2e291b846358a17
```

The server will respond with:

```json
HTTP/1.1 200 OK

{
"message": "comment fetched successfully",
"comment": {
"body": "This is a great post. I love it.",
"tldr": "great post",
"user": "John Doe",
"post": "662659aaa2e291b846358a07",
"id": "66265bcda2e291b846358a17",
"dateCreated": "2024-04-22T12:45:01.875Z",
"dateUpdated": "2024-04-22T12:45:01.875Z"
}
}
```

#### Update a comment

```sh
curl -X PATCH -H "Content-Type: application/json" -H "Authorization: Bearer eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InN1YiI6IjY2MjY1NWMxYTJlMjkxYjg0NjM1ODlmZSIsInJvbGUiOiJhdXRob3IifSwiaWF0IjoxNzEzNzg4MzUzLCJleHAiOjE3MTM5NjExNTN9.8oc3DOAR6SqaWUBynMZlAvHJr202cTXbtiq80EVyO5RSXMJrdGJ-aWdZF_lfR1p4" -d '{
"body": "This is a great post. I love it. I have updated it."
}' http://localhost:3000/api/v1/post-comments/662659aaa2e291b846358a07/comments/66265bcda2e291b846358a17
```

The server will respond with:

```json
HTTP/1.1 200 OK

{
"message": "post comment updated successfully",
"comment": {
"body": "This is a great post. I love it. I have updated it.",
"tldr": "great post",
"user": "John Doe",
"post": "662659aaa2e291b846358a07",
"id": "66265bcda2e291b846358a17",
"dateCreated": "2024-04-22T12:45:01.875Z",
"dateUpdated": "2024-04-22T12:45:01.875Z"
}
}
```

#### Delete a comment

```sh
curl -X DELETE -H "Authorization: Bearer eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InN1YiI6IjY2MjY1NWMxYTJlMjkxYjg0NjM1ODlmZSIsInJvbGUiOiJhdXRob3IifSwiaWF0IjoxNzEzNzg4MzUzLCJleHAiOjE3MTM5NjExNTN9.8oc3DOAR6SqaWUBynMZlAvHJr202cTXbtiq80EVyO5RSXMJrdGJ-aWdZF_lfR1p4" http://localhost:3000/api/v1/post-comments/662659aaa2e291b846358a07/comments/66265bcda2e291b846358a17
```

The server will respond with:

```json
HTTP/1.1 204 No Content
```

#### Add a like to a comment

```sh
curl -X PATCH
-H "Authorization
: Bearer eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InN1YiI6IjY2MjY1NWMxYTJlMjkxYjg0NjM1ODlmZSIsInJvbGUiOiJhdXRob3IifSwiaWF0IjoxNzEzNzg4MzUzLCJleHAiOjE3MTM5NjExNTN9.8oc3DOAR6SqaWUBynMZlAvHJr202cTXbtiq80EVyO5RSXMJrdGJ-aWdZF_lfR1p4" http://localhost:3000/api/v1/post-comments/662659aaa2e291b846358a07/comments/66265bcda2e291b846358a17/likes
```

The server will respond with:

```json
HTTP/1.1 200 OK

{
"message": "like added successfully",
"comment": {
"body": "This is a great post. I love it. I have updated it.",
"tldr": "great post",
"user": "John Doe",
"post": "662659aaa2e291b846358a07",
"id": "66265bcda2e291b846358a17",
"dateCreated": "2024-04-22T12:45:01.875Z",
"dateUpdated": "2024-04-22T12:45:01.875Z",
"likes": 1,
"dislikes": 0
}
}
```

#### Remove a like from a comment

```sh
curl -X DELETE
-H "Authorization
: Bearer eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7InN1YiI6IjY2MjY1NWMxYTJlMjkxYjg0NjM1ODlmZSIsInJvbGUiOiJhdXRob3IifSwiaWF0IjoxNzEzNzg4MzUzLCJleHAiOjE3MTM5NjExNTN9.8oc3DOAR6SqaWUBynMZlAvHJr202cTXbtiq80EVyO5RSXMJrdGJ-aWdZF_lfR1p4" http://localhost:3000/api/v1/post-comments/662659aaa2e291b846358a07/comments/66265bcda2e291b846358a17/likes
```

The server will respond with:

```json
HTTP/1.1 200 OK

{
"message": "like removed successfully",
"comment": {
"body": "This is a great post. I love it. I have updated it.",
"tldr": "great post",
"user": "John Doe",
"post": "662659aaa2e291b846358a07",
"id": "66265bcda2e291b846358a17",
"dateCreated": "2024-04-22T12:45:01.875Z",
"dateUpdated": "2024-04-22T12:45:01.875Z",
"likes": 0,
"dislikes": 0
}
}
```

#### DISLIKES

They follow the same pattern as likes. The only difference is that they are for disliking a comment. The endpoints change from `likes` to `dislikes` but the method remains the same.

#### REPLIES

They follow the same pattern as comments. The only difference is that they are nested under comments.

LICENSE: [Unlicense](https://unlicense.org)