Welcome to my GitHub repository!
This project is a Blog Application API created with Ruby on Rails. It provides a RESTful API for managing blog posts and user authentication. The application uses PostgreSQL for the database, Sidekiq and Redis for scheduling post deletions, and JWT for API authentication. The project includes a docker-compose setup to run the entire stack easily.
- User Authentication
- Post Management
- Docker and Docker Compose installed and running
-
Clone the repository:
git clone https://github.com/yourusername/your-repo-name.git cd your-repo-name -
Set up your .env file:
POSTGRES_DB=blog_api_project POSTGRES_USER={your_user_name} POSTGRES_PASSWORD={your_password} POSTGRES_HOST=db POSTGRES_PORT=5432 -
Build and start the application:
docker-compose up --build
Before accessing any endpoints related to posts, you must sign up or log in to receive a JWT token. This token must be included in the Authorization header as a Bearer token for all subsequent requests to the API.
- Endpoint: POST /signup
- Request Body:
{ "user":{ "name": "name", "email": "name@example.com", "password": "password123", "image": "http://example.com/image.jpg" } } - Response:
{ "token": "your_jwt_token"} - Note Include it in the Authorization header of your requests with the format: Bearer your_jwt_token
- Endpoint: POST /signup
- Request Body:
{ "user":{ "name": "name", "email": "@example.com", "password": "password123", "image": "http://example.com/image.jpg" } } - Response
{ "errors": [ "Email is invalid" ] }
- Endpoint: POST /signup
- Request Body:
{ "user":{ "name": "name", "email": "name@example.com", "password": "pass", "image": "http://example.com/image.jpg" } } - Response:
{ "errors": [ "Password is too short (minimum is 6 characters)" ] }
- Endpoint: POST /signup
- Request Body:
{ "user":{ "name": "name", "email": "name@example.com", "password": "", "image": "http://example.com/image.jpg" } } - Response:
{ "errors": [ "Password can't be blank" ] }
- Endpoint: POST /signup
- Request Body:
{ "user":{ "name": "name", "email": "name@example.com", "password": "password123", "image": "http://example.com/image.jpg" } } - Response:
{ "errors": [ "Email has already been taken" ] }
- Endpoint: POST /login
- Request Body:
{ "email": "john@example.com", "password": "password123" } - Response:
{ "token": "your_jwt_token"} - Note Include it in the Authorization header of your requests with the format: Bearer your_jwt_token
- Endpoint: POST /login
- Request Body:
{ "email": "nameOne@example.com", "password": "password123" } - Response:
{ "error": [ "User_authentication invalid credentials" ] }
- Endpoint: POST /posts (with authentication token)
- Request Body:
{ "post": { "title": "Post title", "body": "Post body content" }, "tags": ["tag1","tag2"] } - Response:
{ "message": "Post created successfully" }
- Endpoint: POST /posts (without authentication token)
- Request Body:
{ "post": { "title": "Post title", "body": "Post body content" }, "tags": ["tag1","tag2"] } - Response:
{ "error": "Not Authorized" }
- Endpoint: POST /posts (without authentication token)
- Request Body:
{ "post": { "title": "Post title", "body": "Post body content" }, "tags": } - Response:
{ "error": "At least one tag is required" }
- Endpoint: GET /posts (with authentication token)
- Response:
[ { "id": 24, "title": "PostOne title", "body": "PostOne body", "user_id": 3, "created_at": "2024-08-16T19:27:20.320Z", "updated_at": "2024-08-16T19:27:20.320Z", "tags": [ { "id": 2, "name": "tag1", "created_at": "2024-08-16T19:14:41.836Z", "updated_at": "2024-08-16T19:14:41.836Z" }, { "id": 3, "name": "tag2", "created_at": "2024-08-16T19:14:41.858Z", "updated_at": "2024-08-16T19:14:41.858Z" } ] }, { "id": 25, "title": "PostTwo title", "body": "PostTwo body", "user_id": 3, "created_at": "2024-08-16T19:27:45.421Z", "updated_at": "2024-08-16T19:27:45.421Z", "tags": [ { "id": 3, "name": "tag2", "created_at": "2024-08-16T19:14:41.858Z", "updated_at": "2024-08-16T19:14:41.858Z" } ] "comments": [ { "id": 1, "body": "comment one on post two", "user_id": 3, "post_id": 25, "created_at": "2024-08-16T20:09:03.385Z", "updated_at": "2024-08-16T20:09:03.385Z", "user": { "id": 3, "email": "john@example.com", "created_at": "2024-08-16T17:20:51.918Z", "updated_at": "2024-08-16T17:20:51.918Z", "name": "name", "image": "http://example.com/image.jpg" } ] }, }, { "id": 26, "title": "PostThree title", "body": "PostThree body", "user_id": 3, "created_at": "2024-08-16T19:28:17.456Z", "updated_at": "2024-08-16T19:28:17.456Z", "tags": [ { "id": 4, "name": "tag3", "created_at": "2024-08-16T19:28:17.475Z", "updated_at": "2024-08-16T19:28:17.475Z" }, { "id": 2, "name": "tag1", "created_at": "2024-08-16T19:14:41.836Z", "updated_at": "2024-08-16T19:14:41.836Z" } ] } ]
- Endpoint: GET /posts/:id (with authentication token)
- Response:
{ "id": 25, "title": "PostTwo title", "body": "PostTwo body", "user_id": 3, "created_at": "2024-08-16T19:27:45.421Z", "updated_at": "2024-08-16T19:27:45.421Z", "tags": [ { "id": 3, "name": "tag2", "created_at": "2024-08-16T19:14:41.858Z", "updated_at": "2024-08-16T19:14:41.858Z" } ] "comments": [ { "id": 1, "body": "comment one on post two", "user_id": 3, "post_id": 25, "created_at": "2024-08-16T20:09:03.385Z", "updated_at": "2024-08-16T20:09:03.385Z", "user": { "id": 3, "email": "john@example.com", "created_at": "2024-08-16T17:20:51.918Z", "updated_at": "2024-08-16T17:20:51.918Z", "name": "name", "image": "http://example.com/image.jpg" } } ] }
- Endpoint: PUT /posts/:id (with the authentication token of the post author)
- Request Body:
{ "post": { "title": "Updated Post Title", "body": "Updated post body content" }, "tags": ["updatedtag1"] } - Response:
{ "message": "Post updated successfully" }
- Endpoint: PUT /posts/:id (with the authentication token of a user but, not the author)
- Request Body:
{ "post": { "title": "Updated Post Title", "body": "Updated post body content" }, "tags": ["updatedtag1"] } - Response:
{ "error": "Not Authorized" }
- Endpoint: PUT /posts/:id (with the authentication token of the user that posted the post)
- Request Body:
{ "post": { "title": "Updated Post Title", "body": "Updated post body content" }, "tags": } - Response:
{ "error": "At least one tag is required" }
- **Endpoint:** DELETE posts/:id (with the authentication token of the post author)
- **Response:**
```bash
{
"message": "Post deleted successfully"
}
- Endpoint: DELETE posts/:id ( with the authentication token of a user but, not the author )
- Response:
{ "error": "Not Authorized" }
- Endpoint: GET
/posts/:post_id/comments(with authentication token) - Response:
[ { "id": 12, "body": "This is a comment", "user_id": 3, "post_id": 25, "created_at": "2024-08-16T19:27:45.421Z", "updated_at": "2024-08-16T19:27:45.421Z" } ]
- Endpoint: GET
/posts/:post_id/comments/:id(with authentication token) - Response:
{ "id": 12, "body": "This is a comment", "user_id": 3, "post_id": 25, "created_at": "2024-08-16T19:27:45.421Z", "updated_at": "2024-08-16T19:27:45.421Z" }
- Endpoint: POST
/posts/:post_id/comments(with authentication token) - Request Body:
{ "comment": { "body": "This is a new comment" } } - Response:
{ "message": "Comment created successfully" }
- Endpoint: POST
/posts/:post_id/comments(with authentication token) - Request Body:
{ "comment": { "body": "" } } - Response:
{ "body": [ "can't be blank" ] }
- Endpoint: PUT
/posts/:post_id/comments/:id(with the authentication token of the comment author) - Request Body:
{ "comment": { "body": "Updated comment content" } } - Response:
{ "message": "Comment updated successfully" }
- Endpoint: PUT
/posts/:post_id/comments/:id(with the authentication token of a user but not the comment author) - Request Body:
{ "comment": { "body": "Updated comment content" } } - Response:
{ "error": "Not Authorized" }
- Endpoint: PUT
/posts/:post_id/comments/:id(with the authentication token of the comment author) - Request Body:
{ "comment": { "body": "" } } - Response:
{ "error": "Comment body cannot be empty" }
- Endpoint: DELETE
/posts/:post_id/comments/:id(with the authentication token of the comment author) - Response:
{ "message": "Comment deleted successfully" }
- Endpoint: DELETE
/posts/:post_id/comments/:id(with the authentication token of a user but not the comment author) - Response:
{ "error": "Not Authorized" }