A REST API for a blog platform built with NestJS, Prisma, PostgreSQL, and JWT-based authentication.
This API currently supports:
- user registration and login
- protected user lookup
- post creation, lookup, update, and deletion
- comment creation, lookup, update, and deletion
- tag creation, lookup, update, and deletion
- role-based access for selected admin-only routes
- ownership-based access for user, post, and comment resources
All routes are served under the global /api prefix.
- NestJS
- TypeScript
- Prisma ORM
- PostgreSQL
- JWT authentication
bcryptjsfor password hashing
src/
auth/ Authentication, login, register, JWT service
comments/ Comment controllers, DTOs, service
decorators/ Custom decorators such as roles metadata
exceptions/ Custom exception classes
filters/ Exception filters
guards/ JWT, role, and ownership guards
posts/ Post controllers, DTOs, service
prisma/ Prisma service and module
shared/ Shared types
tags/ Tag controllers, DTOs, service
users/ User controllers, DTOs, service
The database contains four main models:
UserPostCommentTag
idusernameemailrolebiopasswordHashcreatedAtupdatedAt
idauthorIdcontentattachmentscreatedAtupdatedAt
idauthorIdcontentcreatedAtupdatedAt
idcontentpostId
The API currently uses two roles:
ADMINUSER
Newly created users default to USER.
Authentication is token-based.
POST /api/auth/register
Creates a new user account. Passwords are hashed before storage.
Request body:
{
"username": "alice",
"email": "alice@example.com",
"bio": "Software writer",
"password": "strong-password"
}Response shape:
{
"success": true,
"message": "User created successfully",
"data": {
"id": "uuid",
"username": "alice",
"bio": "Software writer",
"email": "alice@example.com"
}
}POST /api/auth/login
Authenticates a user with username and password, then returns a JWT.
Request body:
{
"username": "alice",
"password": "strong-password"
}Response shape:
{
"success": true,
"message": "Successfully logged in",
"data": {
"token": "jwt-token"
}
}Pass the token in the Authorization header:
Authorization: Bearer <token>Most routes in this API are protected by JwtAuthGuard.
The API currently uses two authorization patterns:
Some routes require the ADMIN role. These routes use:
@Roles(...)RolesGuard
Some routes can only be accessed by:
- the resource owner
- or an admin
These routes use ownership guards such as:
UserOwnershipGuardPostOwnershipGuardCommentOwnershipGuard
POST /api/auth/registerPOST /api/auth/login
-
GET /api/users/:idReturns one user. Access: owner or admin. -
GET /api/users?limit=10Returns a list of users. Access: admin only.
-
GET /api/posts/:idReturns one post. Access: post owner or admin. -
GET /api/posts?limit=10Returns posts. Access: admin only. -
POST /api/postsCreates a post for the authenticated user. -
PUT /api/posts/:idUpdates a post. Access: post owner or admin. -
DELETE /api/posts/:idDeletes a post. Access: post owner or admin.
-
GET /api/comments/:idReturns one comment. Access: comment owner or admin. -
GET /api/comments?limit=10Returns comments. Access: admin only. -
POST /api/commentsCreates a comment for the authenticated user. -
PUT /api/comments/:idUpdates a comment. Access: comment owner or admin. -
DELETE /api/comments/:idDeletes a comment. Access: comment owner or admin.
-
GET /api/tagsReturns tags for authenticated users. -
GET /api/tags/:idReturns one tag for authenticated users. -
POST /api/tagsCreates a tag for authenticated users. -
PUT /api/tags/:idUpdates a tag for authenticated users. -
DELETE /api/tags/:idDeletes a tag. Access: admin only.
Create an .env file in the api directory.
Required variables:
DATABASE_URL=postgresql://USER:PASSWORD@HOST:PORT/DATABASE
JWT_SECRET_KEY=your-secret-key
BCRYPT_SALT_ROUNDS=10
PORT=3000npm installGenerate the Prisma client:
npx prisma generateRun database migrations:
npx prisma migrate devIf you already have migrations and only want to apply them:
npx prisma migrate deploynpm run start:devnpm run startnpm run build
npm run start:prodnpm run build
npm run format
npm run start
npm run start:dev
npm run start:debug
npm run start:prod
npm run lint
npm run test
npm run test:watch
npm run test:cov
npm run test:e2e- Register a user with
POST /api/auth/register - Log in with
POST /api/auth/login - Copy the returned JWT
- Send the token in the
Authorizationheader - Create posts or comments as the authenticated user
- Use an admin account to access admin-only listing and delete routes
The API uses a mix of:
- NestJS built-in exceptions
- custom exceptions such as
PostNotFoundException - exception filters for selected cases
Examples of possible responses include:
401 Unauthorized403 Forbidden404 Not Found409 Conflict
- all routes are prefixed with
/api - post and comment creation use the authenticated user as the author
- the JWT payload includes
id,username,email, androle - Prisma is used directly inside service classes
Possible next improvements for this API:
- add Swagger or OpenAPI documentation
- add pagination metadata to list endpoints
- add refresh tokens
- improve request validation globally
- standardize all error response shapes
- expand automated test coverage
This project has an MIT license.