The Post API manages blog posts, including creation, updates, deletion, and retrieval with advanced filtering and sorting capabilities. Posts support categories, comments, and like/dislike functionality.
Most endpoints are public. Creation, updates, and deletion require authentication. Some operations are restricted to post owners or admins.
GET /api/posts
Returns a paginated list of all posts with advanced filtering and sorting options.
Query Parameters:
page(optional): Page number (default: 1, minimum: 1)limit(optional): Items per page (default: 25, range: 1-100)sort(optional): Sort field - "id", "rating", "created_at", "updated_at" (default: "rating")order(optional): Sort order - "ASC" or "DESC" (default: "ASC")categories(optional): Filter by categories - "all" or comma-separated category names (default: "all")status(optional): Filter by status - "active", "inactive", "all" (default: "all")user(optional): Filter by user ID (default: 0 for all users)from_date(optional): Filter posts from this date (ISO 8601 format)to_date(optional): Filter posts until this date (ISO 8601 format)searchQuery(optional): Filters / orders posts by search query (title & content)
Response:
[
{
"id": 1,
"title": "Introduction to Node.js",
"content": "Node.js is a powerful JavaScript runtime...",
"rating": 25,
"comments_count": 69,
"user_id": 123,
"created_at": "2024-01-15T10:30:00.000Z",
"updated_at": "2024-01-15T10:30:00.000Z",
"deleted_at": null,
"user_reaction": "like" | "dislike" | null,
"categories": [
{
"id": 1,
"title": "Technology",
"description": "Tech-related posts"
}
],
"author": {
"id": 123,
"login": "john_doe"
}
}
]GET /api/posts/:post_id
Returns detailed information about a specific post.
Path Parameters:
post_id: Post ID (integer, minimum: 1)
Response:
{
"id": 1,
"title": "Introduction to Node.js",
"content": "Node.js is a powerful JavaScript runtime...",
"rating": 25,
"user_id": 123,
"created_at": "2024-01-15T10:30:00.000Z",
"updated_at": "2024-01-15T10:30:00.000Z",
"deleted_at": null,
"user_reaction": "like" | "dislike" | null,
"categories": [
{
"id": 1,
"title": "Technology",
"description": "Tech-related posts"
}
],
"author": {
"id": 123,
"login": "john_doe",
"avatar": "avatar.jpg"
},
"comments_count": 5,
"likes_count": 25,
"preview_image_url": "https://image"
}POST /api/posts
Creates a new post.
Authentication: Required
Request Body:
{
"title": "My First Post",
"content": "This is the content of my post...",
"categories": [1, 2, 3]
}Validation Rules:
title: 1-200 characterscontent: 1-5000 characterscategories: Array of category IDs (integers)
Response:
{
"id": 2,
"title": "My First Post",
"content": "This is the content of my post...",
"rating": 0,
"user_id": 123,
"created_at": "2024-01-15T11:00:00.000Z",
"updated_at": "2024-01-15T11:00:00.000Z",
"deleted_at": null,
"categories": [
{
"id": 1,
"title": "Technology"
},
{
"id": 2,
"title": "Programming"
}
]
}PATCH /api/posts/:post_id
Updates an existing post. Only the post creator can update their posts.
Authentication: Required (post owner only)
Path Parameters:
post_id: Post ID (integer, minimum: 1)
Request Body (all fields optional):
{
"title": "Updated Post Title",
"content": "Updated post content...",
"categories": [1, 4]
}Validation Rules:
title: 1-200 characters (if provided)content: 1-5000 characters (if provided)categories: Array of category IDs (if provided)
Response:
{
"id": 2,
"title": "Updated Post Title",
"content": "Updated post content...",
"rating": 0,
"user_id": 123,
"created_at": "2024-01-15T11:00:00.000Z",
"updated_at": "2024-01-15T12:00:00.000Z",
"deleted_at": null,
"categories": [
{
"id": 1,
"title": "Technology"
},
{
"id": 4,
"title": "Web Development"
}
]
}DELETE /api/posts/:post_id
Soft deletes a post. Users can only delete their own posts, admins can delete any post.
Authentication: Required (post owner or admin)
Path Parameters:
post_id: Post ID (integer, minimum: 1)
Response:
- Success: 204 No Content
GET /api/posts/:post_id/categories
Returns all categories associated with a specific post.
Path Parameters:
post_id: Post ID (integer, minimum: 1)
Response:
[
{
"id": 1,
"title": "Technology",
"description": "Tech-related posts"
},
{
"id": 2,
"title": "Programming",
"description": "Programming tutorials and tips"
}
]GET /api/posts/:post_id/comments
Returns all comments for a specific post.
Path Parameters:
post_id: Post ID (integer, minimum: 1)
Response:
[
{
"id": 1,
"content": "Great post!",
"user_id": 456,
"post_id": 1,
"parent_id": null,
"rating": 5,
"created_at": "2024-01-15T12:00:00.000Z",
"updated_at": "2024-01-15T12:00:00.000Z",
"author": {
"id": 456,
"login": "commenter",
"avatar": "avatar2.jpg"
},
"replies": [
{
"id": 2,
"content": "Thanks!",
"user_id": 123,
"post_id": 1,
"parent_id": 1,
"rating": 2,
"created_at": "2024-01-15T12:30:00.000Z",
"updated_at": "2024-01-15T12:30:00.000Z",
"author": {
"id": 123,
"login": "john_doe",
"avatar": "avatar.jpg"
}
}
]
}
]POST /api/posts/:post_id/comments
Creates a new comment on a post.
Authentication: Required
Path Parameters:
post_id: Post ID (integer, minimum: 1)
Request Body:
{
"content": "This is a great post!",
"parent_id": null
}Validation Rules:
content: 1-5000 charactersparent_id: Optional parent comment ID for replies
Response:
{
"id": 3,
"content": "This is a great post!",
"user_id": 456,
"post_id": 1,
"parent_id": null,
"rating": 0,
"created_at": "2024-01-15T13:00:00.000Z",
"updated_at": "2024-01-15T13:00:00.000Z"
}GET /api/posts/:post_id/like
Returns all likes for a specific post.
Path Parameters:
post_id: Post ID (integer, minimum: 1)
Response:
{
"likes": [
{
"id": 1,
"user_id": 456,
"post_id": 1,
"is_like": true,
"created_at": "2024-01-15T12:00:00.000Z",
"user": {
"id": 456,
"login": "liker",
"avatar": "avatar2.jpg"
}
}
]
}POST /api/posts/:post_id/like
POST /api/posts/:post_id/dislike
Likes or dislikes a post. If the user has already liked/disliked, it toggles the action.
Authentication: Required
Path Parameters:
post_id: Post ID (integer, minimum: 1)
Request Body (optional):
{
"action": "like"
}Response:
{
"message": "Post liked successfully"
}DELETE /api/posts/:post_id/like
Removes the user's like or dislike from a post.
Authentication: Required
Path Parameters:
post_id: Post ID (integer, minimum: 1)
Response:
{
"message": "Like removed successfully"
}{
"errors": [
{
"property": "title",
"constraints": {
"minLength": "title must be longer than or equal to 1 characters"
}
}
]
}{
"error": "Invalid or expired access token"
}{
"error": "You can only update your own posts"
}{
"error": "Post not found"
}{
"message": "Post has been deleted"
}The post system utilizes several tables:
id(INT, PRIMARY KEY, AUTO_INCREMENT)title(VARCHAR(200), NOT NULL)content(TEXT, NOT NULL)rating(INT, DEFAULT 0)user_id(INT, FOREIGN KEY to user.id)created_at(DATETIME)updated_at(DATETIME)deleted_at(DATETIME, NULLABLE) - Soft delete
post_id(INT, FOREIGN KEY to post.id)category_id(INT, FOREIGN KEY to category.id)- Primary key on (post_id, category_id)
id(INT, PRIMARY KEY, AUTO_INCREMENT)content(TEXT, NOT NULL)user_id(INT, FOREIGN KEY to user.id)post_id(INT, FOREIGN KEY to post.id)parent_id(INT, FOREIGN KEY to comment.id, NULLABLE)rating(INT, DEFAULT 0)created_at(DATETIME)updated_at(DATETIME)deleted_at(DATETIME, NULLABLE) - Soft delete
id(INT, PRIMARY KEY, AUTO_INCREMENT)user_id(INT, FOREIGN KEY to user.id)post_id(INT, FOREIGN KEY to post.id, NULLABLE)comment_id(INT, FOREIGN KEY to comment.id, NULLABLE)is_like(BOOLEAN, NOT NULL)created_at(DATETIME)- Unique constraint on (user_id, post_id) or (user_id, comment_id)
- id: Sort by post ID
- rating: Sort by number of likes (default)
- created_at: Sort by creation date
- updated_at: Sort by last update date
- categories: Filter by category names (comma-separated)
- status: Filter by post status (active/inactive/all)
- user: Filter by specific user ID
- date range: Filter by creation date using from_date and to_date
curl -X GET "http://localhost:3000/api/posts?categories=technology,programming&sort=rating&order=DESC&limit=10"curl -X POST http://localhost:3000/api/posts \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title": "My Post", "content": "Post content here", "categories": [1, 2]}'curl -X POST http://localhost:3000/api/posts/123/like \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json"curl -X GET "http://localhost:3000/api/posts?from_date=2024-01-01T00:00:00.000Z&to_date=2024-01-31T23:59:59.000Z"