A robust and secure RESTful API for a blogging platform built with Express.js, TypeScript, and MongoDB. The codebase demonstrates modern backend practices including user authentication, roleβbased access control, token management, validation, and structured logging.
- Authentication & Authorization β JWTβbased login/register with refresh tokens; roleβbased access control (admin/user)
- User Management β endpoints for creating, updating, deleting, and fetching user profiles
- Access/Refresh Tokens β secure access tokens with expiration and persistent refresh tokens stored in HTTPβonly cookies and database
- Rate Limiting β prevents abuse with configurable limits
- Security Hardening β Helmet headers, CORS filtering, input validation
- Data Validation β
express-validatorschemas for requests and parameters - Logging β Winston configured for JSON logs with levels and error stacks
- Environment Configuration β centralized
.envsupport with sensible defaults - API Versioning β v1 implemented; v2 scaffolding provided
- HotβReload Development β Nodemon with ts-node for fast iteration
- TypeScript with Path Aliases β clean imports with
@/alias - Graceful Shutdown β database disconnect on SIGTERM/SIGINT
| Component | Technology |
|---|---|
| Runtime | Node.js |
| Language | TypeScript |
| Web Framework | Express.js 5.1.0 |
| Database | MongoDB + Mongoose 8.16.0 |
| Security | Helmet 8.1.0, express-validator |
| Logging | Winston 3.17.0 |
| Rate Limiting | express-rate-limit 7.5.0 |
| Auth | jsonwebtoken, bcrypt |
| Dev Tools | Nodemon, ts-node, Prettier |
- Node.js v16+
- npm v7+
- MongoDB (local or Atlas)
- Clone the repo:
git clone <repository-url> cd blog-api
- Install dependencies:
npm install
- Create a
.envfile (see configuration section below). - Start development server:
Server listens on
npm run dev
http://localhost:${PORT || 3000}by default.
| Variable | Description | Default | Required |
|---|---|---|---|
PORT |
Server port | 3000 | No |
NODE_ENV |
development / production / test |
development | Yes |
MONGO_URI |
MongoDB connection string | β | Yes |
LOG_LEVEL |
Winston log level (error, warn, info, debug) | info | No |
WHITELIST_ORIGINS |
Commaβseparated list of allowed CORS origins | http://localhost:3000 | No |
JWT_ACCESS_SECRET |
Secret used to sign access tokens | β | Yes |
JWT_REFRESH_SECRET |
Secret used to sign refresh tokens | β | Yes |
ACCESS_TOKEN_EXPIRES |
Token lifetime (e.g. "15m", "1h") | β | Yes |
REFRESH_TOKEN_EXPIRES |
Refresh token lifetime (e.g. "7d") | β | Yes |
WHITELIST_ADMIN_MAILS |
Commaβseparated emails allowed to register as admin | see config.ts | No |
Note: The
.env.examplefile provides a template for required values.
Allowed origins are defined in config.WHITELIST_ORIGINS. Modify as needed.
To prevent unauthorized admin signups, only emails in WHITELIST_ADMIN_MAILS may register with role admin.
blog-api/
βββ src/
β βββ server.ts # App entry point, middleware & routes setup
β βββ config/ # Environment and application config
β β βββ index.ts
β βββ controllers/ # Route handlers grouped by version
β β βββ v1/
β β βββ auth/ # register, login, refresh-token, logout
β β βββ user/ # user CRUD and profile endpoints
β βββ routes/
β β βββ v1/ # Express routers for API v1
β βββ middlewares/ # auth, authorization, validation
β βββ models/ # Mongoose schemas (User, Token)
β βββ validators/ # express-validator schemas
β βββ lib/ # shared utilities (jwt, mongoose, rate-limit, winston)
β βββ utils/ # helper functions (random username, etc.)
β βββ @types/ # custom type declarations
β βββ ... # other support code
βββ dist/ # compiled output (ignored in git)
βββ .env.example
βββ nodemon.json
βββ tsconfig.json
βββ package.json
βββ README.md
Base URL: http://localhost:<PORT>/api/v1
| Method | Endpoint | Description | Access |
|---|---|---|---|
| POST | /auth/register |
Create new user (user or admin) |
public |
| POST | /auth/login |
Log in (returns access token & cookie) | public |
| POST | /auth/refresh-token |
Refresh access token using HTTPβonly cookie | public |
| POST | /auth/logout |
Log out and clear refresh token | authenticated |
| Method | Endpoint | Description | Access |
|---|---|---|---|
| GET | /users/current |
Get profile of loggedβin user | auth (user/admin) |
| PUT | /users/current |
Update current user | auth (user/admin) |
| DELETE | /users/current |
Delete own account | auth (user/admin) |
| GET | /users |
List users (paginated) | auth (admin) |
| GET | /users/:userId |
Get specific user by ID | auth (admin) |
| DELETE | /users/:userId |
Delete user by ID | auth (admin) |
limit(integer 1β50, default 20)offset(integer β₯0, default 0)
All endpoints use express-validator; invalid inputs return 400 ValidationError with detailed messages.
Access tokens are sent in Authorization: Bearer <token> header. Refresh tokens are stored in HTTPβonly cookies.
user: basic accessadmin: can view/delete other users and list users
GET /
Returns basic status JSON { message, status, version, timestamp }.
npm run devβ start server with hot reloadnpm run formatβ format source with Prettiernpm run format:checkβ verify formatting
TypeScript is compiled onβtheβfly via ts-node. To build manually:
npx tsc- Helmet secures headers
- CORS whitelisting with origin logging
- Rate Limiting protects endpoints
- JWT & Cookies for session management
- Password Hashing with bcrypt
- Input Validation prevents malformed data
- Environment Isolation sensitive info kept in
.env
- Winston configured for JSON output
- Console transport active in development
- Log levels controlled by
LOG_LEVEL - Errors include stack traces
- Consistent error codes (AuthenticationError, AuthorizationError, ValidationError, NotFound, ServerError)
- Database and startup errors are logged; server exits in production on startup failure.
- Follow TypeScript conventions
- Keep code properly typed
- Add appropriate unit tests (if present)
- Use clear commit messages
- Respect existing file headers and license
Apache License 2.0 β see LICENSE.
Author: HamidRehman
Last Updated: February 2026
Version: 1.0.0
- Express.js Documentation
- TypeScript Documentation
- Mongoose Documentation
- Winston Logger Documentation
- Express Rate Limit Documentation
For issues or questions, please open an issue in this repository.