π RESTful-API Starter Kit
Starter Kit for building modern RESTful APIs with scalable ποΈ, modular π§©, and secure π architecture. Suitable for use as an initial foundation for developing small to large scale backend applications, equipped with various built-in features that are ready to use π§° and easy to develop further π§.
- β
Authentication
- π§Ό Input Validation & Sanitation
- π Password Hashing
- π JWT Token Auth
- π Database Switching (MySQL / PostgreSQL)
- π§© Modular
- π¦ ORM Sequelize
- π§― Handling errors
- ποΈ Scalable Project Structure
- π‘οΈ Rate Limiting
- π Security Headers
- β‘ Redis Caching
- β€οΈ Health Check & Monitoring
- π Asynchronous Task Handling (Bull Queue)
- π₯ Upload File Handlers
- π Graceful Shutdown
- ποΈ Request Profiling
- π HTTP Compression
- π¨ Anomaly Detection
- π Webhook
git clone https://github.com/fitri-hy/restfull-api-starter-nodejs.git
cd restfull-api-starter-nodejs
cp .env.example .env
npm install
npm run dev
π§Ύ Configuration .env Variables
| Variable |
Function |
| HOST |
Server host address |
| PORT |
Port number the application listens on |
| NODE_ENV |
Application mode (development / production) |
| API_KEY_ENABLE |
Enable API key protection |
| API_KEY |
API key value for authentication |
| CORS_ORIGIN |
Allowed origin domain for API access (CORS) |
| DB |
Database type (mysql / postgres) |
| DB_HOST |
Database host address |
| DB_USER |
Database username |
| DB_PASS |
Database password |
| DB_NAME |
Database name |
| DB_PORT |
Database port number |
| WEBHOOK_ENABLE |
Enable webhook notifications |
| WEBHOOK_URL |
Webhook target URL |
| JWT_SECRET |
Secret key to generate JWT tokens |
| JWT_EXPIRATION |
JWT token expiration time (e.g., 1h, 30m) |
| RATE_LIMIT_MAX |
Maximum number of requests before rate limiting |
| RATE_LIMIT_WINDOW_MS |
Rate limit window in milliseconds |
| REDIS_CACHE_ENABLE |
Enable Redis caching |
| REDIS_TASK_ENABLE |
Enable Redis task queue |
| REDIS_HOST |
Redis host address |
| REDIS_PORT |
Redis port number |
| REDIS_TTL |
Time-to-live (TTL) for Redis cache (in seconds) |
| FILE_MAX_SIZE |
Maximum file upload size (in bytes) |
| FILE_UPLOAD_PATH |
Directory path for file uploads |
| FILE_ALLOWED_TYPES |
Allowed file types for upload |
| COMPRESSION_ENABLE |
Enable response compression |
| COMPRESSION_THRESHOLD |
Minimum response size to be compressed |
| COMPRESSION_LEVEL |
Compression level (0-9) |
| ANOMALY_ENABLED |
Enable anomaly detection for requests |
| ANOMALY_TIME |
Time interval for detecting anomalies (in milliseconds) |
| ANOMALY_REQUEST |
Number of suspicious requests before being flagged as an anomaly |
| ANOMALY_URL_LENGTH |
Maximum URL length for anomaly detection |
GET http://localhost:5000/status
POST http://localhost:5000/api/v1/tasks/add
Header Request (If using ApiKey)
| Key |
Value |
| x-api-key |
my_secret_api_key |
GET http://localhost:5000/api/v1/data/:key
Header Request (If using ApiKey)
| Key |
Value |
| x-api-key |
my_secret_api_key |
π€ Example Case (Login, Register, Get All User, User Detail, Edit User Detail)
For testing purposes, you can import the sample.sql sample file available in the /src/config/sample.sql directory.
Download & Import:
RESTful-API_Starter_Kit.postman_collection.json
POST http://localhost:5000/api/v1/auth/register
Header Request (If using ApiKey)
| Key |
Value |
| x-api-key |
my_secret_api_key |
{
"name": "John Doe",
"email": "johndoe@example.com",
"password": "securepassword"
}
{
"message": "Registration successful",
"user": {
"name": "John Doe",
"email": "johndoe@example.com",
"password": "securepassword"
}
}
POST http://localhost:5000/api/v1/auth/login
Header Request (If using ApiKey)
| Key |
Value |
| x-api-key |
my_secret_api_key |
{
"email": "johndoe@example.com",
"password": "securepassword"
}
{
"message": "Login successful",
"token": "your_jwt_token_here"
}
GET http://localhost:5000/api/v1/auth/users
Header Request (If using ApiKey)
| Key |
Value |
| x-api-key |
my_secret_api_key |
Header Authorization:
| Key |
Value |
| Authorization |
Bearer <your_jwt_token_here> |
[
{
"id": 1,
"name": "John Doe",
"email": "johndoe@example.com"
}
...
]
GET http://localhost:5000/api/v1/auth/profile
Header Request (If using ApiKey)
| Key |
Value |
| x-api-key |
my_secret_api_key |
Header Authorization:
| Key |
Value |
| Authorization |
Bearer <your_jwt_token_here> |
{
"id": 1,
"name": "John Doe",
"email": "johndoe@example.com",
"createdAt": "2025-04-21T00:42:41.000Z"
}
PUT http://localhost:5000/api/v1/auth/profile
Header Request (If using ApiKey)
| Key |
Value |
| x-api-key |
my_secret_api_key |
Header Authorization:
| Key |
Value |
| Authorization |
Bearer <your_jwt_token_here> |
{
"name": "John New",
"email": "Johnnew@example.com",
"password": "123456"
}
{
"message": "Profile updated successfully",
"user": {
"id": 1,
"name": "John New",
"email": "Johnnew@example.com",
"createdAt": "2025-04-21T01:13:14.000Z",
"updatedAt": "2025-04-21T01:13:45.000Z"
}
}
POST http://localhost:5000/api/v1/upload/:folderName
Default Location: public/uploads
Header Request (If using ApiKey)
| Key |
Value |
| x-api-key |
my_secret_api_key |
| Key |
Type |
Value |
| file |
file |
Select File |
{
"message": "File uploaded successfully",
"file": {
"fieldname": "file",
"originalname": "your-image.jpeg",
"encoding": "7bit",
"mimetype": "image/jpeg",
"destination": "public/uploads/",
"filename": "1744786296980-815431101.jpeg",
"path": "public\\uploads\\1744786296980-815431101.jpeg",
"size": 582884
}
}
rest-api-starter/
βββ src/
β βββ config/
β βββ controllers/
β βββ middleware/
β βββ models/
β βββ routes/
β βββ service/
β βββ utils/
βββ .env
βββ .gitignore
βββ package.json
βββ app.js