tutorial, express.js,

Membuat RESTful API dengan Express.js: Panduan Lengkap

Kiki/🎮🍉⌨️🍩💻 Kiki/🎮🍉⌨️🍩💻 Aug 23, 2026 · 10 mins read
Membuat RESTful API dengan Express.js: Panduan Lengkap
Share this

REST (Representational State Transfer) adalah arsitektur paling populer untuk membangun API web. Dengan Express.js, kamu bisa membangun RESTful API yang bersih dan terstruktur dengan sangat efisien.

Di artikel ini kita akan membangun API CRUD (Create, Read, Update, Delete) lengkap untuk resource “Artikel” — dari struktur project hingga semua endpoint.


Prinsip RESTful API

REST API mengikuti beberapa konvensi penting:

HTTP Method Endpoint Aksi
GET /artikel Ambil semua artikel
GET /artikel/:id Ambil satu artikel
POST /artikel Buat artikel baru
PUT /artikel/:id Update artikel (replace)
PATCH /artikel/:id Update artikel (partial)
DELETE /artikel/:id Hapus artikel

Konvensi lain yang perlu diikuti:

  • URL menggunakan kata benda (noun), bukan kata kerja — /artikel bukan /ambilArtikel
  • URL menggunakan huruf kecil dan tanda hubung
  • Response menggunakan HTTP status code yang tepat
  • Response body dalam format JSON

Setup Project

mkdir api-artikel
cd api-artikel
npm init -y
npm install express

Struktur folder:

api-artikel/
├── data/
│   └── artikel.js      # "database" in-memory
├── routes/
│   └── artikel.js      # route handlers
├── middleware/
│   └── validasi.js     # validasi input
└── index.js

Data Layer (Simulasi Database)

data/artikel.js — data in-memory sebagai pengganti database:

let artikel = [
  {
    id: 1,
    judul: 'Pengenalan Express.js',
    konten: 'Express adalah framework minimalis untuk Node.js...',
    kategori: 'tutorial',
    penulis: 'Budi',
    dibuatPada: new Date('2026-08-19').toISOString()
  },
  {
    id: 2,
    judul: 'Routing di Express',
    konten: 'Routing menentukan bagaimana aplikasi merespons request...',
    kategori: 'tutorial',
    penulis: 'Sari',
    dibuatPada: new Date('2026-08-20').toISOString()
  }
];

let idCounter = artikel.length + 1;

module.exports = {
  getAll: () => artikel,
  getById: (id) => artikel.find(a => a.id === id),
  create: (data) => {
    const baru = { id: idCounter++, ...data, dibuatPada: new Date().toISOString() };
    artikel.push(baru);
    return baru;
  },
  update: (id, data) => {
    const index = artikel.findIndex(a => a.id === id);
    if (index === -1) return null;
    artikel[index] = { ...artikel[index], ...data };
    return artikel[index];
  },
  delete: (id) => {
    const index = artikel.findIndex(a => a.id === id);
    if (index === -1) return false;
    artikel.splice(index, 1);
    return true;
  }
};

Route Handlers

routes/artikel.js:

const express = require('express');
const router = express.Router();
const db = require('../data/artikel');

// GET /artikel — ambil semua dengan pagination & filter
router.get('/', (req, res) => {
  let data = db.getAll();

  // Filter berdasarkan kategori
  if (req.query.kategori) {
    data = data.filter(a => a.kategori === req.query.kategori);
  }

  // Pencarian judul
  if (req.query.q) {
    const keyword = req.query.q.toLowerCase();
    data = data.filter(a => a.judul.toLowerCase().includes(keyword));
  }

  // Pagination
  const halaman = parseInt(req.query.halaman) || 1;
  const limit = parseInt(req.query.limit) || 10;
  const offset = (halaman - 1) * limit;
  const paginasi = data.slice(offset, offset + limit);

  res.json({
    total: data.length,
    halaman,
    limit,
    data: paginasi
  });
});

// GET /artikel/:id — ambil satu artikel
router.get('/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const item = db.getById(id);

  if (!item) {
    return res.status(404).json({ error: 'Artikel tidak ditemukan' });
  }

  res.json(item);
});

// POST /artikel — buat artikel baru
router.post('/', (req, res) => {
  const { judul, konten, kategori, penulis } = req.body;

  if (!judul || !konten) {
    return res.status(422).json({ error: 'Judul dan konten wajib diisi' });
  }

  const baru = db.create({ judul, konten, kategori: kategori || 'umum', penulis: penulis || 'Anonim' });
  res.status(201).json(baru);
});

// PUT /artikel/:id — update penuh
router.put('/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const { judul, konten, kategori, penulis } = req.body;

  if (!judul || !konten) {
    return res.status(422).json({ error: 'Judul dan konten wajib diisi' });
  }

  const diupdate = db.update(id, { judul, konten, kategori, penulis });
  if (!diupdate) return res.status(404).json({ error: 'Artikel tidak ditemukan' });

  res.json(diupdate);
});

// PATCH /artikel/:id — update sebagian
router.patch('/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const diupdate = db.update(id, req.body);

  if (!diupdate) return res.status(404).json({ error: 'Artikel tidak ditemukan' });

  res.json(diupdate);
});

// DELETE /artikel/:id — hapus artikel
router.delete('/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const berhasil = db.delete(id);

  if (!berhasil) return res.status(404).json({ error: 'Artikel tidak ditemukan' });

  res.status(204).send();
});

module.exports = router;

Entry Point

index.js:

const express = require('express');
const app = express();

app.use(express.json());

// Routes
const artikelRouter = require('./routes/artikel');
app.use('/api/artikel', artikelRouter);

// 404 handler
app.use((req, res) => {
  res.status(404).json({ error: 'Endpoint tidak ditemukan' });
});

// Error handler
app.use((err, req, res, next) => {
  console.error(err);
  res.status(500).json({ error: 'Terjadi kesalahan server' });
});

app.listen(3000, () => {
  console.log('API berjalan di http://localhost:3000');
});

Test API dengan curl

# Ambil semua artikel
curl http://localhost:3000/api/artikel

# Ambil dengan filter
curl "http://localhost:3000/api/artikel?kategori=tutorial&halaman=1"

# Buat artikel baru
curl -X POST http://localhost:3000/api/artikel \
  -H "Content-Type: application/json" \
  -d '{"judul":"Artikel Baru","konten":"Isi artikel...","kategori":"tutorial"}'

# Update artikel
curl -X PATCH http://localhost:3000/api/artikel/1 \
  -H "Content-Type: application/json" \
  -d '{"judul":"Judul Diperbarui"}'

# Hapus artikel
curl -X DELETE http://localhost:3000/api/artikel/1

HTTP Status Code yang Tepat

Situasi Status Code
Berhasil mengambil data 200 OK
Berhasil membuat resource 201 Created
Berhasil hapus (no content) 204 No Content
Input tidak valid 422 Unprocessable Entity
Tidak ditemukan 404 Not Found
Tidak terautentikasi 401 Unauthorized
Tidak diizinkan 403 Forbidden
Kesalahan server 500 Internal Server Error

Kesimpulan

Dengan Express.js, membangun RESTful API yang bersih dan terstruktur sangat mudah. Kunci utamanya adalah mengikuti konvensi REST — URL sebagai noun, HTTP method sesuai aksi, dan status code yang tepat.

Di artikel berikutnya, kita hubungkan API ini ke database nyata menggunakan Prisma ORM agar data tersimpan secara persisten.

Kiki/🎮🍉⌨️🍩💻
Written by Kiki/🎮🍉⌨️🍩💻
hello I'm friend K.