Di bab ini kita benar-benar membuat REST API yang dipakai di dunia nyata, bukan simulasi array.
Namun tetap simple dan masuk akal untuk blog, tanpa ORM, tanpa struktur berlebihan.
Target API:
- CRUD data dari MySQL
- koneksi database pakai mysql2
- query SQL langsung (mudah dipahami)
- struktur backend rapi tapi tidak ribet
Studi kasus: Data Produk
Contents
- 1 Struktur Folder Backend yang Digunakan
- 2 Membuat Database dan Tabel MySQL
- 3 Install mysql2
- 4 Koneksi MySQL Menggunakan mysql2
- 5 Setup Aplikasi Express
- 6 Entry Point Server
- 7 Controller: Ambil Semua Produk (GET)
- 8 Controller: Ambil Produk by ID
- 9 Controller: Tambah Produk (POST)
- 10 Controller: Update Produk (PUT)
- 11 Controller: Hapus Produk (DELETE)
- 12 Routing REST API Produk
- 13 Daftar Endpoint REST API
- 14 Contoh Testing (POST)
- 15 Kenapa Pendekatan Ini Ideal untuk Blog
- 16 Kesimpulan
- 17 Related Posts
Struktur Folder Backend yang Digunakan
Struktur ini cukup profesional tapi tetap sederhana:
backend/
├── src/
│ ├── routes/
│ │ └── product.routes.js
│ ├── controllers/
│ │ └── product.controller.js
│ ├── db/
│ │ └── mysql.js
│ └── app.js
├── index.js
├── package.json
Tidak ada service layer dulu → biar fokus MySQL + REST API.
Membuat Database dan Tabel MySQL
Buat database dan tabel sederhana:
CREATE DATABASE node_api;
USE node_api;
CREATE TABLE products (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100),
price INT
);
Struktur ini cukup untuk latihan REST API.
Install mysql2
npm install express mysql2
mysql2 dipilih karena:
- cepat
- stabil
- paling umum dipakai di Node.js
Koneksi MySQL Menggunakan mysql2
// src/db/mysql.js
import mysql from "mysql2/promise";
const db = mysql.createPool({
host: "localhost",
user: "root",
password: "",
database: "node_api"
});
export default db;
Kenapa createPool?
- koneksi lebih stabil
- cocok untuk API
Setup Aplikasi Express
// src/app.js
import express from "express";
import productRoutes from "./routes/product.routes.js";
const app = express();
app.use(express.json());
app.use("/api/products", productRoutes);
export default app;
Entry Point Server
// index.js
import app from "./src/app.js";
app.listen(3000, () => {
console.log("Server berjalan di http://localhost:3000");
});
Controller: Ambil Semua Produk (GET)
// src/controllers/product.controller.js
import db from "../db/mysql.js";
export async function getProducts(req, res) {
const [rows] = await db.query("SELECT * FROM products");
res.json({
success: true,
data: rows
});
}
Ini REST API nyata, langsung query ke MySQL.
Controller: Ambil Produk by ID
export async function getProductById(req, res) {
const id = req.params.id;
const [rows] = await db.query(
"SELECT * FROM products WHERE id = ?",
); if (rows.length === 0) { return res.status(404).json({ message: "Produk tidak ditemukan" }); } res.json({ success: true, data: rows[0] }); }
? mencegah SQL Injection → WAJIB.
Controller: Tambah Produk (POST)
export async function createProduct(req, res) {
const { name, price } = req.body;
if (!name || !price) {
return res.status(400).json({
message: "Name dan price wajib diisi"
});
}
const [result] = await db.query(
"INSERT INTO products (name, price) VALUES (?, ?)",
); res.status(201).json({ success: true, data: { id: result.insertId, name, price } }); }
Controller: Update Produk (PUT)
export async function updateProduct(req, res) {
const id = req.params.id;
const { name, price } = req.body;
const [result] = await db.query(
"UPDATE products SET name = ?, price = ? WHERE id = ?",
); if (result.affectedRows === 0) { return res.status(404).json({ message: "Produk tidak ditemukan" }); } res.json({ success: true, message: "Produk berhasil diupdate" }); }
Controller: Hapus Produk (DELETE)
export async function deleteProduct(req, res) {
const id = req.params.id;
const [result] = await db.query(
"DELETE FROM products WHERE id = ?",
); if (result.affectedRows === 0) { return res.status(404).json({ message: "Produk tidak ditemukan" }); } res.json({ success: true, message: "Produk berhasil dihapus" }); }
Routing REST API Produk
// src/routes/product.routes.js
import express from "express";
import {
getProducts,
getProductById,
createProduct,
updateProduct,
deleteProduct
} from "../controllers/product.controller.js";
const router = express.Router();
router.get("/", getProducts);
router.get("/:id", getProductById);
router.post("/", createProduct);
router.put("/:id", updateProduct);
router.delete("/:id", deleteProduct);
export default router;
Daftar Endpoint REST API
| Method | Endpoint | Fungsi |
|---|---|---|
| GET | /api/products | Ambil semua produk |
| GET | /api/products/:id | Detail produk |
| POST | /api/products | Tambah produk |
| PUT | /api/products/:id | Update produk |
| DELETE | /api/products/:id | Hapus produk |
Ini REST API MySQL yang benar dan minimal.
Contoh Testing (POST)
Body JSON:
{
"name": "Keyboard",
"price": 300000
}
Response:
{
"success": true,
"data": {
"id": 1,
"name": "Keyboard",
"price": 300000
}
}
Kenapa Pendekatan Ini Ideal untuk Blog
✔ pakai database sungguhan
✔ kode singkat dan jelas
✔ tidak terlalu abstrak
✔ mudah dikembangkan ke JWT & auth
✔ cocok untuk pembaca pemula–menengah
Ini bukan contoh murahan, tapi fondasi backend nyata.
Kesimpulan
Dengan mysql2 dan Express:
- REST API bisa dibuat ringkas dan profesional
- tidak perlu ORM untuk belajar konsep backend
- alur data jadi jelas dan logis
Bab ini adalah jembatan ke backend serius.