OpenAPI definition (v0)

Download OpenAPI specification:Download

Authentication

User authentication and registration endpoints

Register a new user

Creates a new user account and returns JWT authentication tokens.

Requirements

  • Username: 3-16 characters, must be unique
  • Email: Valid email format, must be unique
  • Password: Minimum 8 characters

Response

Returns a token pair upon successful registration:

  • Access Token: Short-lived token for API authentication (15 min)
  • Refresh Token: Long-lived token for obtaining new access tokens (30 days)

Security

  • Password is hashed using BCrypt before storage
  • Tokens are signed using HS256 algorithm
  • No sensitive data is included in JWT payload
Request Body schema: application/json
required
username
required
string [ 3 .. 16 ] characters

Unique username (3-16 alphanumeric characters)

password
required
string <password> [ 8 .. 2147483647 ] characters

Account password (minimum 8 characters)

email
required
string <email> non-empty

Valid email address (must be unique)

Responses

Request samples

Content type
application/json
{
  • "username": "johndoe",
  • "password": "SecurePass123!",
  • "email": "john.doe@example.com"
}

Response samples

Content type
application/json

Returns JWT tokens for immediate authentication

{
  • "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJqb2huZG9lIiwiaWF0IjoxNzAzMjU2MDAwLCJleHAiOjE3MDMyNTY5MDB9.signature",
  • "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJqb2huZG9lIiwiaWF0IjoxNzAzMjU2MDAwLCJleHAiOjE3MDM4NjA4MDB9.signature"
}

Refresh access token

Generates a new access token using a valid refresh token.

Requirements

  • Valid refresh token obtained from login or registration
  • Token must not be expired
  • Token type must be "refresh"

Response

Returns a new access token with updated expiration:

  • Access Token: Short-lived token for API authentication (15 min)

Use Case

Use this endpoint when your access token has expired but your refresh token is still valid. This allows maintaining user session without requiring re-authentication.

Security

  • Refresh token is validated and verified
  • User claims are preserved from the original refresh token
  • Only refresh token type is accepted (access tokens will be rejected)
Request Body schema: application/json
required
refreshToken
required
string non-empty

Long-lived refresh token used to obtain a new access token

Responses

Request samples

Content type
application/json
{
  • "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjMiLCJ0eXBlIjoicmVmcmVzaCIsImlhdCI6MTcwMzI1NjAwMCwiZXhwIjoxNzA1ODQ4MDAwfQ.signature"
}

Response samples

Content type
application/json

Fresh access token with updated expiration

{
  • "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjMiLCJ1c2VybmFtZSI6ImpvaG5kb2UiLCJpYXQiOjE3MDMyNTYwMDAsImV4cCI6MTcwMzI1NjkwMH0.signature"
}

Logout user and revoke refresh token

Revokes a refresh token to invalidate all active sessions using that token.

Requirements

  • Valid refresh token obtained from login or registration
  • Token must not have been previously revoked

Response

Returns HTTP 204 No Content on successful revocation

Use Case

Use this endpoint when a user explicitly logs out or when you need to invalidate a specific refresh token for security purposes (e.g., device logout).

Security

  • Token is hashed before storage to prevent token exposure
  • Expired tokens are automatically cleaned up by scheduled task
  • Once revoked, the token cannot be used to refresh access tokens
  • Duplicate revocation attempts return 409 Conflict
Request Body schema: application/json
required
refreshToken
required
string non-empty

Refresh token to be revoked and invalidated

Responses

Request samples

Content type
application/json
{
  • "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Response samples

Content type
application/json
Example

Missing Refresh Token

{
  • "timestamp": "2026-01-16T16:16:26",
  • "status": 400,
  • "error": "Bad Request",
  • "message": "Validation Failed",
  • "path": "/auth/logout",
  • "errors": [
    ]
}

Login user

Authenticates an existing user and returns JWT authentication tokens.

Requirements

  • Username or Email: Valid username or email address
  • Password: User's password

Response

Returns a token pair upon successful authentication:

  • Access Token: Short-lived token for API authentication (15 min)
  • Refresh Token: Long-lived token for obtaining new access tokens (30 days)

Security

  • Password is verified using BCrypt
  • Tokens are signed using HS256 algorithm
  • No sensitive data is included in JWT payload
Request Body schema: application/json
required
usernameOrEmail
required
string non-empty

Username or email address

password
required
string non-empty

User password

Responses

Request samples

Content type
application/json
{
  • "usernameOrEmail": "string",
  • "password": "string"
}

Response samples

Content type
application/json

Returns JWT tokens for authentication

{
  • "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJqb2huZG9lIiwiaWF0IjoxNzAzMjU2MDAwLCJleHAiOjE3MDMyNTY5MDB9.signature",
  • "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJqb2huZG9lIiwiaWF0IjoxNzAzMjU2MDAwLCJleHAiOjE3MDM4NjA4MDB9.signature"
}

Get authenticated user information

Returns the currently authenticated user's principal information extracted from the JWT token.

Requirements

  • Valid JWT access token must be provided in Authorization header
  • Token must not be expired

Response

Returns user principal containing:

  • User ID: Unique user identifier
  • Username: User's username
  • Email: User's email address
  • Profile Picture URL: URL to user's profile picture (if set)

Security

  • Requires authentication via Bearer token
  • Only returns information for the authenticated user

Responses

Response samples

Content type
application/json

User details extracted from JWT token

{}

Posts

Create a new post with preview image

Creates a new blog post with a preview image uploaded to S3 storage.

Requirements

  • Authentication: Valid JWT access token required
  • Title: Required, non-blank string
  • Description: Required, non-blank string for post summary
  • Content: Required, non-blank markdown or text content
  • Preview Image: Required multipart file (JPEG, PNG, GIF)

Response

Returns the created post details with generated slug and preview image URL upon success (201).

Behavior

  • Preview image is uploaded to S3 storage
  • Unique slug is auto-generated from the title
  • Post is saved with current timestamp
  • Returns full post details including file URL

Security

  • Requires valid JWT token in Authorization header
  • Author is automatically set from authenticated user
  • File upload validates content type and size
Request Body schema: multipart/form-data
required
required
object (PostCreateRequestDTO)

Request DTO for creating a new post

previewImage
required
string <binary>

Responses

Response samples

Content type
application/json

Returns complete post details including generated slug and image URL

{
  • "id": 1,
  • "title": "My First Blog Post",
  • "description": "An introduction to my blog",
  • "content": "This is the full content of my first blog post...",
  • "slug": "my-first-blog-post",
  • "createdAt": "2026-01-21T23:00:00"
}

Delete a post by ID

Deletes a specific post from the system by its unique identifier.

Requirements

  • Post ID: Must be a valid post identifier that exists in the system

Response

Returns no content (204) upon successful deletion.

Behavior

  • Post is permanently removed from the database
  • If post doesn't exist, returns 404 Not Found
  • If deletion fails due to database errors, returns 500 Internal Server Error
path Parameters
postId
required
integer <int64>

Responses

Response samples

Content type
application/json

Invalid JWT Token

{
  • "timestamp": "2026-01-16T16:15:06",
  • "status": 401,
  • "error": "Unauthorized",
  • "message": "Invalid or expired JWT token",
  • "path": "/posts/7"
}

Update a post by ID with optional preview image

Updates a specific post with partial field updates by its unique identifier. Accepts multipart/form-data with JSON post data and optional preview image.

Requirements

  • Authentication: Valid JWT access token required
  • Post ID: Must be a valid post identifier that exists in the system
  • At least one field: Must provide at least one field to update (title, description, or content)
  • Form Data Parts:
    • post (required): JSON object with PostUpdateRequestDTO
    • previewImage (optional): Multipart file (JPEG, PNG, GIF)

Response

Returns the updated post details (200) upon success.

Behavior

  • Only provided fields are updated; null fields are ignored
  • Slug is automatically regenerated if title is updated
  • Preview image replaces existing image if provided
  • Old preview image is deleted when new one is uploaded
  • If post doesn't exist, returns 404 Not Found
  • If no fields provided, returns 400 Bad Request
  • If update fails due to database errors, returns 500 Internal Server Error

Security

  • Requires valid JWT token in Authorization header
  • Only post owner can update the post (verified via @PostSecurity)
path Parameters
postId
required
integer <int64>
Request Body schema: multipart/form-data
required
required
object (PostUpdateRequestDTO)

Request DTO for updating a post

previewImage
string <binary>

Responses

Response samples

Content type
application/json

Returns updated post with all current field values and new preview image URL

{}

Get a post by slug

Retrieves a specific post from the system by its unique slug identifier, including all associated comments.

Requirements

  • Slug: Must be a valid post slug that exists in the system

Response

Returns the post details with associated comments (200) upon success.

Behavior

  • Post and its comments are retrieved from the database
  • If post doesn't exist, returns 404 Not Found
  • If retrieval fails due to database errors, returns 500 Internal Server Error
path Parameters
slug
required
string

Responses

Response samples

Content type
application/json

Post Not Found

{
  • "timestamp": "2026-01-16T16:16:26",
  • "status": 404,
  • "error": "Not Found",
  • "message": "Post not found",
  • "path": "/posts/my-post-slug"
}

Reactions

Set or update a reaction on a post

Sets or updates the authenticated user's reaction on a specific post.

Requirements

  • Authentication: Valid JWT access token required
  • Post ID: Must be a valid post identifier that exists in the system
  • Reaction Type: Must be either LIKE or DISLIKE

Response

Returns the created or updated reaction details (200) upon success.

Behavior

  • If user has already reacted to the post, updates the reaction type
  • If user hasn't reacted yet, creates a new reaction
  • Users can change their reaction from LIKE to DISLIKE or vice versa
  • If post doesn't exist, returns 404 Not Found
  • If reaction type is invalid, returns 400 Bad Request
  • If user is not authenticated, returns 401 Unauthorized
  • If save fails due to database errors, returns 500 Internal Server Error
path Parameters
postId
required
integer <int64>
Request Body schema: application/json
required
reactionType
required
string
Enum: "LIKE" "DISLIKE"

Type of the reaction

Responses

Request samples

Content type
application/json
{
  • "reactionType": "LIKE"
}

Response samples

Content type
application/json

Returns the reaction with all details

{
  • "id": 1,
  • "reactionType": "LIKE",
  • "userId": 7,
  • "postId": 42
}

Comments

Create a comment on a post

Creates a new comment on a specific post by the authenticated user.

Requirements

  • Authentication: Valid JWT access token required
  • Post ID: Must be a valid post identifier that exists in the system
  • Content: Comment content must not be blank

Response

Returns the created comment details (201) upon success.

Behavior

  • Comment is associated with the authenticated user as the author
  • Comment is associated with the specified post
  • If post doesn't exist, returns appropriate error
  • If content validation fails, returns 400 Bad Request
  • If user is not authenticated, returns 401 Unauthorized
path Parameters
postId
required
integer <int64>
Request Body schema: application/json
required
content
required
string non-empty

The content of the comment

Responses

Request samples

Content type
application/json
{
  • "content": "This is a comment."
}

Response samples

Content type
application/json

Returns the created comment with metadata

{
  • "id": 1,
  • "content": "This is a great post! Thanks for sharing.",
  • "postId": 42,
  • "authorId": 7,
  • "createdAt": "2026-02-10T00:30:00",
  • "updatedAt": "2026-02-10T00:30:00",
  • "edited": false
}

Delete a comment by ID

Deletes a specific comment from the system by its unique identifier.

Requirements

  • Authentication: Valid JWT access token required
  • Comment ID: Must be a valid comment identifier that exists in the system
  • Ownership: User must be the owner of the comment to delete it

Response

Returns no content (204) upon successful deletion.

Behavior

  • Comment is permanently removed from the database
  • Only the comment author can delete their own comment
  • If comment doesn't exist, returns 404 Not Found
  • If user is not the owner, returns 403 Forbidden
  • If user is not authenticated, returns 401 Unauthorized
  • If deletion fails due to database errors, returns 500 Internal Server Error
path Parameters
commentId
required
integer <int64>

Responses

Response samples

Content type
application/json

Invalid JWT Token

{
  • "timestamp": "2026-02-10T15:07:00",
  • "status": 401,
  • "error": "Unauthorized",
  • "message": "Invalid or expired JWT token",
  • "path": "/comments/42"
}

Update a comment by ID

Updates a specific comment's content by its unique identifier.

Requirements

  • Authentication: Valid JWT access token required
  • Comment ID: Must be a valid comment identifier that exists in the system
  • Ownership: User must be the owner of the comment to update it
  • Content: Comment content must not be blank

Response

Returns the updated comment details (200) upon success.

Behavior

  • Comment content is updated in the database
  • Comment is marked as edited with updated timestamp
  • Only the comment author can update their own comment
  • If comment doesn't exist, returns 404 Not Found
  • If user is not the owner, returns 403 Forbidden
  • If content validation fails, returns 400 Bad Request
  • If user is not authenticated, returns 401 Unauthorized
  • If update fails due to database errors, returns 500 Internal Server Error
path Parameters
commentId
required
integer <int64>
Request Body schema: application/json
required
content
required
string non-empty

The content of the comment

Responses

Request samples

Content type
application/json
{
  • "content": "This is a comment."
}

Response samples

Content type
application/json

Returns the updated comment with edited flag set to true

{
  • "id": 42,
  • "content": "This is the updated comment content.",
  • "postId": 7,
  • "authorId": 3,
  • "createdAt": "2026-02-10T10:00:00",
  • "updatedAt": "2026-02-10T22:55:00",
  • "edited": true
}

Users

Update authenticated user's profile

Updates the authenticated user's profile information including bio, email, username, password, and profile picture.

Authentication

Requires a valid JWT access token in the Authorization header.

Supported Updates

  • Email: New email address (must be unique)
  • Username: New username (must be unique)
  • Bio: User biography/description
  • Password: New password (will be hashed before storage)
  • Profile Picture: New profile picture image file (multipart upload)

Partial Updates

All fields are optional. Only provide the fields you want to update. Omitted fields will retain their current values.

Profile Picture Handling

  • If a new profile picture is provided, the old one is deleted automatically
  • Supported formats: JPEG, PNG, GIF
  • Maximum file size: 5MB

Security

  • Password is hashed using BCrypt before storage
  • Users can only update their own profile
  • Username and email uniqueness is enforced
Authorizations:
None
Request Body schema: multipart/form-data
required
object (UpdateUserRequestDTO)
profilePicture
string <binary>

Responses

Response samples

Content type
application/json
Example

Returns updated profile information

{}

Get user profile by username

Retrieves complete user profile information including bio, profile picture, and all posts.

Requirements

  • Username: Valid username that exists in the system

Response

Returns user profile data including:

  • Username: The user's unique username
  • Bio: User's biography/description
  • Profile Picture URL: URL to the user's profile picture
  • Posts: List of all posts by the user with summaries

Use Case

Use this endpoint to display a user's profile page with their posts.

path Parameters
username
required
string

Responses

Response samples

Content type
application/json

Returns user information and their published posts

{
  • "username": "johndoe",
  • "bio": "Software developer passionate about clean code and best practices.",
  • "posts": [
    ]
}