☀️Siang
Software Engineering

API Design Best Practices: Panduan Lengkap 2026

TOKEN

Panduan lengkap merancang API yang baik — konsep REST, URL design, versioning, documentation, testing, authentication, error handling, rate limiting, dan tips membangun API yang developer-friendly

Artikel: Skill Api Design Artikel: Skill Api Design


1. Pengenalan: Mengapa API Design Penting?

API (Application Programming Interface) adalah jantung dari hampir semua aplikasi modern. Setiap kali kamu membuka aplikasi mobile, memesan makanan online, atau menggunakan media sosial, ada API yang bekerja di balik layar untuk mengirim dan menerima data.

API yang dirancang dengan baik akan:

  • Mempercepat development: Developer bisa menggunakan API dengan cepat tanpa perlu membaca dokumentasi panjang
  • Mengurangi bugs: Endpoint yang intuitif dan konsisten mengurangi kesalahan integrasi
  • Mudah di-maintain: Struktur yang terorganisir mempermudah update dan perbaikan di masa depan
  • Scalable: API yang baik bisa menangani pertumbuhan traffic tanpa perlu redesign
  • Meningkatkan adoption: Developer lebih suka menggunakan API yang konsisten dan well-documented

Menurut Postman State of the API Report 2025, 92% perusahaan teknologi mengandalkan API sebagai komponen utama bisnis mereka. Di Indonesia, API-first development menjadi tren yang semakin populer di startup dan enterprise.

Diagram: Arsitektur API
flowchart TB
    Client["📱 Client\n(Mobile/Web/IoT)"] -->|"HTTP Request"| Gateway["🌐 API Gateway\n(Auth, Rate Limit, Routing)"]
    Gateway --> Auth["🔐 Auth Service\n(JWT/OAuth)"]
    Gateway --> Service1["🔧 Service A\n(Users)"]
    Gateway --> Service2["🔧 Service B\n(Products)"]
    Gateway --> Service3["🔧 Service C\n(Orders)"]
    
    Service1 & Service2 & Service3 --> DB["("#quot;🗄️ Database#quot;")"]
    Service1 & Service2 & Service3 --> Cache["⚡ Redis Cache"]

    style Client fill:#2a0f1e,stroke:#f472b6
    style Gateway fill:#2a1f0a,stroke:#f59e0b,stroke-width:2px
    style Auth fill:#2a0f0f,stroke:#ef4444,stroke-width:1.5px
    style Service1 fill:#0f2a1f,stroke:#3ecf8e
    style Service2 fill:#0f1d3a,stroke:#60a5fa
    style Service3 fill:#1a0f2e,stroke:#a78bfa
    style DB fill:#0a2a1f,stroke:#34d399
    style Cache fill:#0f2a1f,stroke:#3ecf8e

Jenis-Jenis API

Jenis API Protocol Data Format Use Case
RESTHTTP/HTTPSJSON (utama), XMLWeb & mobile apps (paling populer)
GraphQLHTTP/HTTPSJSONComplex data fetching, mobile apps
gRPCHTTP/2Protocol BuffersMicroservices internal communication
WebSocketWS/WSSJSON, binaryReal-time (chat, live data)
SOAPHTTP, SMTPXMLLegacy enterprise systems


2. REST API Fundamentals

REST (Representational State Transfer) adalah arsitektural style untuk mendesain API berbasis HTTP. RESTful API adalah standar industri untuk web API.

Prinsip REST

Prinsip Penjelasan Implementasi
StatelessSetiap request harus mandiri, server tidak menyimpan state clientToken-based auth (JWT), no server sessions
Client-ServerClient dan server terpisah, bisa berkembang independenFrontend dan backend terpisah
Uniform InterfaceAntarmuka yang konsisten dan terstandarisasiURL naming conventions, HTTP methods
CacheableResponse bisa di-cache untuk meningkatkan performaCache-Control headers, ETag
Layered SystemClient tidak perlu tahu apakah langsung ke server atau melalui proxyAPI Gateway, Load Balancer, CDN
Code on Demand (opsional)Server bisa mengirim executable code ke clientJavaScript dalam response (jarang digunakan)

Contoh REST API: Blog Platform

// Resource: Articles

// GET    /api/v1/articles          → Ambil semua artikel
// GET    /api/v1/articles/:id      → Ambil artikel by ID
// POST   /api/v1/articles          → Buat artikel baru
// PUT    /api/v1/articles/:id      → Update artikel (full)
// PATCH  /api/v1/articles/:id      → Update artikel (partial)
// DELETE /api/v1/articles/:id      → Hapus artikel

// Resource: Article Comments
// GET    /api/v1/articles/:id/comments       → Ambil semua komentar
// POST   /api/v1/articles/:id/comments       → Tambah komentar

// Resource: Users
// GET    /api/v1/users/:id/articles          → Artikel milik user
// GET    /api/v1/users/:id                   → Detail user


3. URL Design & Resource Naming

URL yang konsisten dan intuitif adalah tanda API yang baik. Berikut best practices untuk URL design:

✅ Best Practices URL Design

Aturan ✅ Benar ❌ Salah
Gunakan noun (bukan verb)/api/v1/users/api/getUsers, /api/createUser
Gunakan plural untuk collections/api/v1/articles/api/v1/article
Gunakan lowercase/api/v1/user-profiles/api/v1/UserProfiles
Gunakan hyphens (bukan underscores)/api/v1/user-profiles/api/v1/user_profiles
Hierarchical resource nesting/api/v1/users/123/orders/api/v1/userOrders?userId=123
Max 3 level nesting/api/v1/users/123/orders/api/v1/users/123/orders/456/items/789
Gunakan query params untuk filter/api/v1/articles?status=published/api/v1/articles/published
Consistent across all endpointsSemua endpoint pakai /api/v1/Beberapa pakai /v1/, beberapa tanpa prefix

🎯 Contoh URL Design yang Baik

// ✅ GOOD: Resource-oriented, consistent, intuitive
GET    /api/v1/users                    → Daftar semua user
GET    /api/v1/users/123                → Detail user #123
POST   /api/v1/users                    → Buat user baru
PATCH  /api/v1/users/123                → Update user #123
DELETE /api/v1/users/123                → Hapus user #123

// ✅ GOOD: Sub-resource (nested)
GET    /api/v1/users/123/orders         → Order milik user #123
POST   /api/v1/users/123/orders         → Buat order untuk user #123

// ✅ GOOD: Actions yang tidak bisa di-representasikan dengan CRUD
POST   /api/v1/orders/456/cancel        → Cancel order
POST   /api/v1/users/123/verify-email   → Verifikasi email
POST   /api/v1/auth/login               → Login
POST   /api/v1/auth/refresh-token       → Refresh access token

// ✅ GOOD: Query parameters untuk filter, sort, paginate
GET    /api/v1/articles?status=published&category=tech&sort=-created_at&page=1&limit=20
GET    /api/v1/products?min_price=10000&max_price=100000&brand=nike

// ❌ BAD: Action-based URLs
GET    /api/getAllUsers
POST   /api/createNewUser
POST   /api/deleteUser
GET    /api/fetchUserOrders?userId=123

🔍 Query Parameters Best Practices

Parameter Type Convention Contoh
Filteringfield_name=value?status=active&category=tech
Sortingsort=field atau sort=-field (descending)?sort=-created_at&sort=name
Pagination (offset)page & limit atau offset & limit?page=2&limit=20
Pagination (cursor)cursor & limit?cursor=abc123&limit=20
Searchq=keyword atau search=keyword
Field selectionfields=field1,field2?fields=name,email,avatar
Embedding relatedinclude=relation atau embed=relation?include=author,comments


4. HTTP Methods & Status Codes

HTTP Methods yang Benar

Method Fungsi Idempotent? Contoh
GETMengambil data (read)✅ YaGET /api/v1/users
POSTMembuat data baru (create)❌ TidakPOST /api/v1/users
PUTUpdate seluruh resource✅ YaPUT /api/v1/users/123
PATCHUpdate sebagian resource❌ Tidak (biasanya)PATCH /api/v1/users/123
DELETEMenghapus resource✅ YaDELETE /api/v1/users/123
HEADSeperti GET tapi tanpa body✅ YaHEAD /api/v1/users/123
OPTIONSInformasi tentang allowed methods✅ YaOPTIONS /api/v1/users

HTTP Status Codes yang Tepat

✅ Sukses (2xx)

CodeMeaningKapan Digunakan
200 OKBerhasilGET, PUT, PATCH yang berhasil
201 CreatedResource berhasil dibuatPOST yang berhasil membuat resource baru
204 No ContentBerhasil, tidak ada response bodyDELETE yang berhasil
202 AcceptedRequest diterima, diproses asyncBackground job queued

⚠️ Client Error (4xx)

CodeMeaningKapan Digunakan
400 Bad RequestRequest tidak validValidasi gagal, format salah
401 UnauthorizedTidak terautentikasiToken tidak ada atau expired
403 ForbiddenTidak punya izinAuthenticated tapi tidak punya akses
404 Not FoundResource tidak ditemukanID tidak ada di database
409 ConflictKonflik dengan stateDuplicate email, concurrent update
422 Unprocessable EntityValidasi gagalFormat benar tapi value tidak valid
429 Too Many RequestsRate limit exceededClient terlalu banyak request

🔴 Server Error (5xx)

CodeMeaningKapan Digunakan
500 Internal Server ErrorError di serverUnhandled exception
502 Bad GatewayGateway/proxy errorUpstream service down
503 Service UnavailableService sedang downMaintenance, overload
504 Gateway TimeoutTimeout dari upstreamRequest terlalu lama


5. API Versioning Strategies

Versioning sangat penting untuk API yang digunakan oleh banyak consumer. Tanpa versioning, perubahan API bisa memecah integrasi yang sudah ada.

Strategi Versioning

Diagram: API Versioning Approaches
API Versioning Approaches

QUERY PARAMETER

HEADER VERSIONING

URL PATH VERSIONING

/api/v1/users

/api/v2/users

Accept: application/vnd.api.v1+json

Accept: application/vnd.api.v2+json

/api/users?version=1

/api/users?version=2

Strategi Contoh Kelebihan Kekurangan
URL Path/api/v1/usersJelas, mudah dipahami, cache-friendlyURL jadi lebih panjang
HeaderX-API-Version: 1URL tetap bersihTidak visible, sulit di-cache
Query Param/api/users?v=1Mudah digunakanOpasional, sering terlewat
Content NegotiationAccept: application/vnd.app.v1+jsonPaling fleksibel, teknis tepatKompleks, sulit dipahami pemula

Best Practices API Versioning

  • Gunakan URL path versioning sebagai default — paling mudah dipahami developer
  • Mulai dari v1 dari awal — jangan tunggu sampai butuh breaking change baru bikin versi
  • Semantic versioning: Major (breaking changes), minor (new features), patch (bug fixes)
  • Dokumentasikan perubahan: Migrasi guide, changelog, deprecation timeline
  • Support versi lama: Minimal 6-12 bulan setelah versi baru dirilis
  • Deprecation headers: Sertakan header peringatan saat versi akan dihentikan
// Contoh API versioning dengan backward compatibility

// API v1 (legacy)
GET /api/v1/users/123
// Response:
{
  "id": 123,
  "name": "John Doe",
  "email": "john@example.com"
}

// API v2 (improved — field berubah)
GET /api/v2/users/123
// Response:
{
  "id": 123,
  "first_name": "John",
  "last_name": "Doe",
  "email": "john@example.com",
  "avatar_url": "https://...",
  "created_at": "2026-01-15T10:30:00Z"
}

// Deprecation header untuk v1
// HTTP/1.1 200 OK
// X-API-Deprecation-Date: 2026-12-31
// X-API-Deprecation-Info: Use /api/v2/users instead


6. Authentication & Authorization

Keamanan API adalah aspek kritis. Berikut metode authentication dan authorization yang umum digunakan:

Metode Authentication

Metode Cara Kerja Kelebihan Kekurangan Use Case
API KeyKey dikirim di header/querySederhanaTidak ada expiry, kurang amanPublic API, server-to-server
JWT (Bearer Token)Token signed di Authorization headerStateless, scalableToken bisa besar, revocation sulitWeb & mobile apps
OAuth 2.0Authorization code flowAman, standardizedKompleks untuk setup3rd party integration
Session CookieCookie berisi session IDMudah, built-in browserStateful, CORS issuesTraditional web apps

JWT Best Practices

// JWT Flow:
// 1. Client login → server berikan access_token + refresh_token
// 2. Client kirim access_token di setiap request
// 3. Token expired → client gunakan refresh_token untuk dapat access_token baru

// Request dengan JWT:
GET /api/v1/users/123
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

// Login response:
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4...",
  "token_type": "Bearer",
  "expires_in": 3600
}

// Refresh token request:
POST /api/v1/auth/refresh
{
  "refresh_token": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4..."
}

Authorization (RBAC)

// Role-Based Access Control (RBAC):
// User      → bisa akses resource miliknya sendiri
// Editor    → bisa update semua artikel
// Admin     → bisa akses semua endpoint

// Contoh response 403 Forbidden:
{
  "error": {
    "code": "FORBIDDEN",
    "message": "You don't have permission to access this resource",
    "details": "Required role: admin, your role: user"
  }
}


7. Error Handling & Response Format

Format response yang konsisten — baik untuk sukses maupun error — sangat penting untuk developer experience:

Standard Response Format

// ✅ Success Response:
{
  "status": "success",
  "data": {
    "id": 123,
    "name": "John Doe",
    "email": "john@example.com"
  },
  "meta": {
    "request_id": "req_abc123def456",
    "timestamp": "2026-06-26T10:30:00Z"
  }
}

// ✅ Success Response (List):
{
  "status": "success",
  "data": [
    { "id": 1, "name": "John" },
    { "id": 2, "name": "Jane" }
  ],
  "meta": {
    "page": 1,
    "limit": 20,
    "total": 150,
    "total_pages": 8
  }
}

// ✅ Error Response:
{
  "status": "error",
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request validation failed",
    "details": [
      { "field": "email", "message": "Invalid email format" },
      { "field": "password", "message": "Password must be at least 8 characters" }
    ]
  },
  "meta": {
    "request_id": "req_abc123def456",
    "timestamp": "2026-06-26T10:30:00Z"
  }
}

Contoh Error Responses

ScenarioStatusError CodeMessage
Validasi gagal422VALIDATION_ERRORField X tidak valid
Resource tidak ada404NOT_FOUNDUser dengan ID 123 tidak ditemukan
Email duplicate409CONFLICTEmail sudah terdaftar
Token expired401TOKEN_EXPIREDAccess token has expired
Akses ditolak403FORBIDDENTidak punya akses ke resource ini
Rate limit429RATE_LIMIT_EXCEEDEDToo many requests, try again later
Server error500INTERNAL_ERRORSomething went wrong


8. Pagination, Filtering & Sorting

Offset-Based Pagination

// Request:
GET /api/v1/articles?page=2&limit=20

// Response:
{
  "data": [...],
  "meta": {
    "page": 2,
    "limit": 20,
    "total": 150,
    "total_pages": 8,
    "has_next": true,
    "has_prev": true
  }
}

Cursor-Based Pagination (untuk dataset besar)

// Request:
GET /api/v1/articles?cursor=eyJpZCI6MTAwfQ==&limit=20

// Response:
{
  "data": [...],
  "meta": {
    "next_cursor": "eyJpZCI6MTIwfQ==",
    "has_more": true
  }
}

Filtering & Sorting

// Filter dengan multiple conditions
GET /api/v1/products?category=electronics&min_price=100000&in_stock=true

// Sort ascending dan descending
GET /api/v1/articles?sort=-created_at,title
// -created_at = descending, title = ascending

// Field selection
GET /api/v1/users?fields=id,name,email,avatar

// Include related resources
GET /api/v1/articles?include=author,category,comments


9. API Documentation

API yang tidak didokumentasikan dengan baik adalah API yang tidak akan digunakan. Berikut best practices untuk API documentation:

Tools API Documentation

Tools Tipe Kelebihan
OpenAPI (Swagger)Specification (YAML/JSON)Industry standard, banyak tools
Swagger UIInteractive docsAuto-generate dari OpenAPI spec
RedocDocumentation rendererBeautiful, responsive docs
PostmanAPI platformCollections, testing, mock server
StoplightDesign-first platformVisual editor, mock server
ReadmeDeveloper portalCustomizable, analytics, versioning

Contoh OpenAPI Specification (Snippet)

openapi: 3.0.3
info:
  title: BeebaneLabs API
  version: 1.0.0
  description: API untuk platform tutorial BeebaneLabs

paths:
  /api/v1/articles:
    get:
      summary: Daftar semua artikel
      description: Mengambil daftar artikel dengan pagination
      parameters:
        - name: page
          in: query
          schema:
            type: integer
            default: 1
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
            maximum: 100
        - name: category
          in: query
          schema:
            type: string
      responses:
        '200':
          description: Berhasil
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Article'
                  meta:
                    $ref: '#/components/schemas/PaginationMeta'
    post:
      summary: Buat artikel baru
      security:
        - bearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ArticleCreate'
      responses:
        '201':
          description: Artikel berhasil dibuat
        '422':
          description: Validasi gagal

Apa yang Harus Ada di API Documentation

  1. Getting Started Guide: Quick start, authentication setup, first request
  2. Authentication: Cara mendapatkan token, refresh, dan handle error
  3. Endpoint Reference: Semua endpoint dengan request/response examples
  4. Error Codes: Daftar lengkap error codes dan cara handle
  5. Rate Limits: Limitasi dan cara menghandle rate limiting
  6. Changelog: Perubahan di setiap versi
  7. SDKs & Code Examples: Contoh penggunaan di berbagai bahasa
  8. Webhook Documentation: Events, payload format, retry policy


10. API Testing

Level API Testing

Level Tujuan Tools
Unit TestingTest individual functions/validatorsJest, pytest, Go testing
Integration TestingTest endpoint dengan databaseSupertest, pytest + httpx
Contract TestingTest kesesuaian dengan API specPact, Dredd, Schemathesis
Performance TestingTest load & stressk6, Artillery, Apache Bench
Security TestingTest vulnerabilitiesOWASP ZAP, Burp Suite
E2E TestingTest full workflowPostman, Newman, REST Assured

Contoh API Testing (JavaScript/Jest)

// Integration test dengan Jest + Supertest
const request = require('supertest');
const app = require('../app');

describe('Articles API', () => {
  let authToken;

  beforeAll(async () => {
    // Login untuk mendapatkan token
    const res = await request(app)
      .post('/api/v1/auth/login')
      .send({ email: 'test@example.com', password: 'password123' });
    authToken = res.body.data.access_token;
  });

  describe('GET /api/v1/articles', () => {
    it('should return list of articles', async () => {
      const res = await request(app)
        .get('/api/v1/articles')
        .expect(200);

      expect(res.body.status).toBe('success');
      expect(Array.isArray(res.body.data)).toBe(true);
      expect(res.body.meta).toHaveProperty('page');
      expect(res.body.meta).toHaveProperty('total');
    });

    it('should filter articles by category', async () => {
      const res = await request(app)
        .get('/api/v1/articles?category=javascript')
        .expect(200);

      res.body.data.forEach(article => {
        expect(article.category).toBe('javascript');
      });
    });
  });

  describe('POST /api/v1/articles', () => {
    it('should create new article', async () => {
      const res = await request(app)
        .post('/api/v1/articles')
        .set('Authorization', `Bearer ${authToken}`)
        .send({
          title: 'Test Article',
          content: 'This is test content',
          category: 'testing'
        })
        .expect(201);

      expect(res.body.data).toHaveProperty('id');
      expect(res.body.data.title).toBe('Test Article');
    });

    it('should return 422 for invalid data', async () => {
      const res = await request(app)
        .post('/api/v1/articles')
        .set('Authorization', `Bearer ${authToken}`)
        .send({ title: '' })
        .expect(422);

      expect(res.body.error.code).toBe('VALIDATION_ERROR');
    });

    it('should return 401 without auth token', async () => {
      await request(app)
        .post('/api/v1/articles')
        .send({ title: 'Test' })
        .expect(401);
    });
  });
});


11. Rate Limiting & Caching

Rate Limiting Best Practices

Tier Limit Window Contoh Response Header
Free100 requestsPer menitX-RateLimit-Limit: 100
Basic1,000 requestsPer menitX-RateLimit-Limit: 1000
Premium10,000 requestsPer menitX-RateLimit-Limit: 10000
// Rate limit response headers
X-RateLimit-Limit: 100          // Max requests per window
X-RateLimit-Remaining: 75       // Remaining requests
X-RateLimit-Reset: 1687812000   // Unix timestamp when limit resets

// Response 429 Too Many Requests:
{
  "status": "error",
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Too many requests. Please try again in 30 seconds.",
    "retry_after": 30
  }
}

// Header:
Retry-After: 30

Caching Strategies

Strategy Header Contoh Use Case
No CacheCache-Control: no-storeSensitive dataUser profile, transactions
Short CacheCache-Control: max-age=60Data berubah sesekaliProduct list, news
Long CacheCache-Control: max-age=86400Data jarang berubahCategories, countries
ETagETag: "abc123"Conditional requestLarge resources
Last-ModifiedLast-Modified: Wed, 26 Jun 2026Conditional requestFile-based resources


12. Security Best Practices

Checklist Keamanan API

Keamanan Implementasi Prioritas
HTTPS OnlyRedirect HTTP → HTTPS, HSTS header⭐⭐⭐⭐⭐
Input ValidationValidasi semua input di server, sanitize⭐⭐⭐⭐⭐
Parameterized QueriesHindari SQL injection dengan ORM/prepared statement⭐⭐⭐⭐⭐
CORS ConfigurationWhitelist allowed origins⭐⭐⭐⭐⭐
Rate LimitingPrevent brute force & DDoS⭐⭐⭐⭐⭐
AuthenticationJWT/OAuth2 dengan token expiry yang tepat⭐⭐⭐⭐⭐
AuthorizationRBAC, check permission di setiap endpoint⭐⭐⭐⭐⭐
Security HeadersX-Content-Type-Options, X-Frame-Options, CSP⭐⭐⭐⭐
Request Size LimitBatasi ukuran request body (misal 1MB)⭐⭐⭐⭐
Logging & MonitoringLog semua request, alert untuk suspicious activity⭐⭐⭐⭐
API Keys RotationRotate API keys secara berkala⭐⭐⭐
Data EncryptionEncrypt sensitive data at rest & in transit⭐⭐⭐⭐⭐


13. API Design Checklist

📋 Checklist Perancangan API
Aspek Checklist Item Status
URL Design✅ Gunakan nouns, bukan verbs
URL Design✅ Plural nouns untuk collections
URL Design✅ Konsisten lowercase + hyphens
URL Design✅ Versioning di URL (/api/v1/)
HTTP Methods✅ HTTP methods benar (GET/POST/PUT/PATCH/DELETE)
Status Codes✅ Status codes yang tepat
Response Format✅ Consistent JSON response format
Error Handling✅ Meaningful error messages
Authentication✅ JWT/OAuth2 implementation
Authorization✅ RBAC/permission check
Pagination✅ Pagination di semua list endpoints
Filtering✅ Query params untuk filter/sort/search
Rate Limiting✅ Rate limit headers
Caching✅ Cache-Control headers
Documentation✅ OpenAPI/Swagger spec
Testing✅ Integration & unit tests
Security✅ HTTPS, input validation, CORS
Logging✅ Request/response logging
Monitoring✅ Health check endpoint
Performance✅ Request size limits

14. Quiz Pemahaman

1. HTTP method yang tepat untuk membuat resource baru adalah?

2. URL mana yang paling sesuai dengan REST best practices?

3. Status code yang tepat ketika resource berhasil dibuat adalah?

4. Metode API versioning yang paling populer dan mudah dipahami adalah?

5. Status code yang digunakan ketika client melebihi rate limit adalah?

🔍 Zoom
100%
🎨 Tema