Dokumentasi lengkap pembuatan backend API RESTful dengan Node.js, Express, Prisma ORM, dan SQLite.
- Node.js (v16 atau lebih tinggi)
- npm atau yarn
- Postman atau REST Client untuk testing API
- Text Editor (VS Code, Sublime, dll)
cd C:\xampp\htdocs\backend-nodeJS
npm init -ynpm install express cors dotenv helmet express-rate-limit zod pino pino-pretty
npm install -D prisma nodemonPenjelasan dependencies:
express- Framework webcors- Menangani Cross-Origin Requestsdotenv- Manajemen environment variableshelmet- Security middlewareexpress-rate-limit- Rate limiting untuk APIzod- Validasi schemapino- Logger untuk productionprisma- ORM databasenodemon- Auto-reload saat development
Buat file .env di root project:
DATABASE_URL="file:./dev.db"
PORT=3000
NODE_ENV=development
CORS_ORIGIN=http://localhost:3000
RATE_LIMIT_WINDOW_MS=900000
RATE_LIMIT_MAX_REQUESTS=100
LOG_LEVEL=infonpx prisma initEdit prisma/schema.prisma:
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String
phone String?
address String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Product {
id Int @id @default(autoincrement())
name String
description String?
price Float
stock Int @default(0)
category String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}npx prisma migrate dev --name initPerintah ini akan:
- Membuat file database
dev.db - Membuat folder
prisma/migrations - Generate Prisma Client
Buat file src/config/database.js:
const { PrismaClient } = require('@prisma/client');
const prisma = new PrismaClient();
module.exports = prisma;File: src/schemas/userSchema.js
const { z } = require('zod');
exports.userSchema = z.object({
email: z.string().email(),
name: z.string().min(3),
phone: z.string().optional(),
address: z.string().optional()
});File: src/schemas/productSchema.js
const { z } = require('zod');
exports.productSchema = z.object({
name: z.string(),
price: z.number(),
stock: z.number(),
description: z.string().optional(),
category: z.string().optional()
});File: src/controllers/userController.js
const prisma = require('../config/database');
exports.getAllUsers = async (req, res) => {
const users = await prisma.user.findMany();
res.json(users);
};
exports.getUserById = async (req, res) => {
const user = await prisma.user.findUnique({
where: { id: Number(req.params.id) }
});
if (!user) return res.status(404).json({ message: 'User tidak ditemukan' });
res.json(user);
};
exports.createUser = async (req, res) => {
const user = await prisma.user.create({ data: req.body });
res.status(201).json(user);
};
exports.updateUser = async (req, res) => {
const user = await prisma.user.update({
where: { id: Number(req.params.id) },
data: req.body
});
res.json(user);
};
exports.deleteUser = async (req, res) => {
await prisma.user.delete({
where: { id: Number(req.params.id) }
});
res.json({ message: 'User dihapus' });
};File: src/controllers/productController.js
const prisma = require('../config/database');
exports.getAllProducts = async (req, res) => {
const data = await prisma.product.findMany();
res.json(data);
};
exports.getProductById = async (req, res) => {
const data = await prisma.product.findUnique({
where: { id: Number(req.params.id) }
});
if (!data) return res.status(404).json({ message: 'Product tidak ditemukan' });
res.json(data);
};
exports.createProduct = async (req, res) => {
const data = await prisma.product.create({ data: req.body });
res.status(201).json(data);
};
exports.updateProduct = async (req, res) => {
const data = await prisma.product.update({
where: { id: Number(req.params.id) },
data: req.body
});
res.json(data);
};
exports.deleteProduct = async (req, res) => {
await prisma.product.delete({
where: { id: Number(req.params.id) }
});
res.json({ message: 'Product dihapus' });
};File: src/routes/userRoutes.js
const express = require('express');
const router = express.Router();
const controller = require('../controllers/userController');
router.get('/', controller.getAllUsers);
router.get('/:id', controller.getUserById);
router.post('/', controller.createUser);
router.put('/:id', controller.updateUser);
router.delete('/:id', controller.deleteUser);
module.exports = router;File: src/routes/productRoutes.js
const express = require('express');
const router = express.Router();
const controller = require('../controllers/productController');
router.get('/', controller.getAllProducts);
router.get('/:id', controller.getProductById);
router.post('/', controller.createProduct);
router.put('/:id', controller.updateProduct);
router.delete('/:id', controller.deleteProduct);
module.exports = router;File: server.js
require('dotenv').config();
const express = require('express');
const helmet = require('helmet');
const cors = require('cors');
const rateLimit = require('express-rate-limit');
const app = express();
// Security
app.use(helmet());
// JSON reader
app.use(express.json());
// CORS
app.use(cors({
origin: process.env.CORS_ORIGIN.split(',')
}));
// Rate limiter
app.use(rateLimit({
windowMs: parseInt(process.env.RATE_LIMIT_WINDOW_MS),
max: parseInt(process.env.RATE_LIMIT_MAX_REQUESTS)
}));
// Routes
app.use('/api/users', require('./src/routes/userRoutes'));
app.use('/api/products', require('./src/routes/productRoutes'));
// Health Check
app.get('/api/health', (req, res) => {
res.json({ status: 'OK', message: 'Server berjalan' });
});
// Global Error Handler
app.use((err, req, res, next) => {
res.status(500).json({
message: 'Internal Server Error',
error: err.message
});
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running di http://localhost:${PORT}`);
});Edit package.json dan tambahkan scripts:
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js",
"prisma:migrate": "npx prisma migrate dev",
"prisma:studio": "npx prisma studio"
}npm run devOutput yang diharapkan:
Server running di http://localhost:3000
backend-nodeJS/
├── prisma/
│ ├── schema.prisma
│ └── migrations/
├── src/
│ ├── config/
│ │ └── database.js
│ ├── controllers/
│ │ ├── userController.js
│ │ └── productController.js
│ ├── routes/
│ │ ├── userRoutes.js
│ │ └── productRoutes.js
│ └── schemas/
│ ├── userSchema.js
│ └── productSchema.js
├── .env
├── .gitignore
├── package.json
├── prisma.config.ts
├── server.js
└── dev.db (database file)
GET /api/health- Check server status
GET /api/users- Get all usersGET /api/users/:id- Get user by IDPOST /api/users- Create new userPUT /api/users/:id- Update userDELETE /api/users/:id- Delete user
GET /api/products- Get all productsGET /api/products/:id- Get product by IDPOST /api/products- Create new productPUT /api/products/:id- Update productDELETE /api/products/:id- Delete product
Buka: http://localhost:3000/api/health
Response:
{
"status": "OK",
"message": "Server berjalan"
}- Method:
POST - URL:
http://localhost:3000/api/users - Body (JSON):
{
"email": "user@example.com",
"name": "John Doe",
"phone": "08123456789",
"address": "Jl. Merdeka No. 1"
}- Method:
GET - URL:
http://localhost:3000/api/users
- Method:
GET - URL:
http://localhost:3000/api/users/1
- Method:
PUT - URL:
http://localhost:3000/api/users/1 - Body (JSON):
{
"name": "Jane Doe",
"phone": "08987654321"
}- Method:
DELETE - URL:
http://localhost:3000/api/users/1
npm run prisma:studioAkan membuka UI di browser untuk melihat dan mengedit data database secara visual.
# Development
npm run dev # Run server dengan nodemon
# Production
npm start # Run server
# Database
npm run prisma:migrate # Run migration
npm run prisma:studio # Open Prisma Studio
# Prisma
npx prisma generate # Generate Prisma Client
npx prisma db push # Push schema ke database- Environment Variables - Semua sensitive data di
.env - Helmet.js - Protect HTTP headers
- CORS - Kontrol akses cross-origin
- Rate Limiting - Prevent DDoS attacks
- Input Validation - Gunakan Zod untuk validasi
npm install @prisma/client
npx prisma generate# Delete dan regenerate database
rm prisma/dev.db
npx prisma migrate dev --name initUbah PORT di .env atau gunakan:
PORT=3001 npm run devMIT
Backend Node.js Setup Guide - 2025