CODE-GENERATION OPENAPI GRAPHQL SCHEMA-DRIVEN-DEVELOPMENT FULLSTACK DEVELOPER-EXPERIENCE AUTOMATION TYPESCRIPT API-DEVELOPMENT CONSISTENCY PRODUCTIVITY DEVOPS CI-CD

Otomatisasi Penuh Stack Anda: Kekuatan Code Generation dari Skema API (OpenAPI & GraphQL)

⏱️ 12 menit baca
👨‍💻

Otomatisasi Penuh Stack Anda: Kekuatan Code Generation dari Skema API (OpenAPI & GraphQL)

1. Pendahuluan

Pernahkah Anda merasa frustrasi saat mengembangkan aplikasi full-stack? Frontend dan backend Anda berbicara bahasa yang sama (JSON atau data terstruktur lainnya), tapi terkadang mereka seperti berada di dunia yang berbeda. Perubahan kecil di API backend seringkali berarti Anda harus memperbarui model data, validasi, dan klien API secara manual di frontend. Ini repetitif, rawan kesalahan, dan memakan waktu. 😫

Di sinilah Code Generation dari Skema API datang sebagai penyelamat! Bayangkan memiliki “cetak biru” tunggal untuk API Anda, dan dari cetak biru itu, kode untuk frontend, backend, bahkan mock server bisa dihasilkan secara otomatis. Tidak ada lagi sinkronisasi manual, tidak ada lagi any yang menyedihkan di TypeScript Anda, dan yang paling penting, lebih sedikit bug dan waktu pengembangan yang lebih cepat.

Artikel ini akan membawa Anda menyelami bagaimana memanfaatkan kekuatan skema API seperti OpenAPI (sebelumnya Swagger) dan GraphQL untuk mengotomatisasi sebagian besar boilerplate kode Anda. Kita akan melihat contoh konkret, manfaatnya, dan bagaimana mengintegrasikannya ke dalam workflow pengembangan Anda.

2. Apa Itu Code Generation dari Skema API?

Pada intinya, code generation dari skema API adalah proses mengambil definisi API yang terstruktur dan menghasilkan kode sumber berdasarkan definisi tersebut. Skema API bertindak sebagai single source of truth atau satu-satunya sumber kebenaran untuk seluruh kontrak komunikasi antara berbagai bagian aplikasi Anda.

💡 Analogi: Bayangkan Anda adalah seorang arsitek. Skema API adalah gambar desain lengkap rumah yang Anda buat. Dengan gambar ini, Anda bisa secara otomatis menghasilkan daftar material (tipe data), instruksi pembangunan pondasi (backend stubs), instruksi pembangunan interior (frontend client), dan bahkan model 3D rumah (mock server) tanpa harus menggambar ulang semuanya dari awal setiap kali ada perubahan kecil pada desain.

Manfaat utamanya adalah:

Mari kita lihat bagaimana ini bekerja dengan OpenAPI dan GraphQL.

3. OpenAPI: Generating Code untuk Backend dan Frontend

OpenAPI Specification adalah standar yang independen dari bahasa untuk mendefinisikan RESTful API. Ini memungkinkan Anda menjelaskan semua endpoint, operasi, parameter, dan model data API Anda dalam format yang dapat dibaca manusia dan mesin (YAML atau JSON).

3.1. Code Generation untuk Backend

Di sisi backend, OpenAPI dapat membantu Anda menghasilkan:

📌 Contoh Praktis (Node.js dengan Express): Misalnya, Anda memiliki definisi OpenAPI berikut untuk endpoint /users:

# openapi.yaml
openapi: 3.0.0
info:
  title: User API
  version: 1.0.0
paths:
  /users:
    get:
      summary: Get all users
      responses:
        '200':
          description: A list of users
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/User'
components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        email:
          type: string
          format: email
      required:
        - id
        - name
        - email

Anda bisa menggunakan tool seperti openapi-generator-cli untuk menghasilkan kerangka server:

npx @openapitools/openapi-generator-cli generate -i openapi.yaml -g nodejs-express -o ./backend-generated

Ini akan menghasilkan folder backend-generated berisi struktur proyek Express dengan controller dan model data yang sudah terdefinisi sesuai skema Anda.

3.2. Code Generation untuk Frontend

Di sisi frontend, OpenAPI adalah tambang emas untuk:

📌 Contoh Praktis (React/TypeScript): Melanjutkan contoh openapi.yaml di atas, Anda bisa menghasilkan klien API dan tipe data TypeScript:

npx @openapitools/openapi-generator-cli generate -i openapi.yaml -g typescript-axios -o ./frontend-generated

Atau tool lain yang lebih spesifik untuk TypeScript seperti openapi-typescript-codegen:

npm install -D openapi-typescript-codegen
# atau
yarn add -D openapi-typescript-codegen

# Jalankan script di package.json
# "generate:api": "openapi --input ./openapi.yaml --output ./src/api --client axios"

Setelah dijalankan, Anda akan mendapatkan file-file seperti src/api/index.ts yang berisi klien Axios yang sudah terkonfigurasi dan src/api/models.ts dengan interface TypeScript seperti:

// src/api/models.ts (contoh hasil generate)
export interface User {
  id: string;
  name: string;
  email: string;
}

// src/api/services/UserService.ts (contoh hasil generate)
import { ApiClient } from '../ApiClient';
import { User } from '../models';

export class UserService {
  constructor(private client: ApiClient) {}

  public async getUsers(): Promise<User[]> {
    const response = await this.client.request({
      method: 'GET',
      url: '/users',
    });
    return response.data;
  }
}

Masalah yang Dihindari: Menulis interface User { id: string; name: string; email: string; } secara manual di frontend dan backend, lalu lupa mengupdate salah satunya ketika ada perubahan.

3.3. Mock Servers Cepat

OpenAPI juga memungkinkan Anda dengan cepat membuat mock server yang mengembalikan data sesuai skema. Ini sangat berguna untuk pengembangan frontend paralel, di mana frontend bisa mulai bekerja tanpa menunggu backend selesai. Tool seperti json-server dengan plugin OpenAPI atau Stoplight Prism dapat melakukannya.

4. GraphQL: Kekuatan Type Safety End-to-End

GraphQL secara inheren sangat cocok untuk code generation karena sifatnya yang kuat dalam sistem tipe. Setiap query, mutation, dan subscription sudah memiliki definisi tipe yang jelas.

4.1. Code Generation untuk Frontend

GraphQL bersinar di frontend dengan tool seperti graphql-codegen. Tool ini dapat menghasilkan:

📌 Contoh Praktis (React/TypeScript dengan Apollo Client): Anda memiliki skema GraphQL dan sebuah query:

# schema.graphql
type User {
  id: ID!
  name: String!
  email: String!
}

type Query {
  users: [User!]!
  user(id: ID!): User
}
# src/queries/getUsers.graphql
query GetUsers {
  users {
    id
    name
    email
  }
}

Dengan graphql-codegen, Anda bisa mengkonfigurasi codegen.ts (atau codegen.yml):

// codegen.ts
import type { CodegenConfig } from '@graphql-codegen/cli';

const config: CodegenConfig = {
  overwrite: true,
  schema: "schema.graphql", // Path ke skema GraphQL Anda
  documents: "src/**/*.graphql", // Path ke semua file query/mutation/fragment Anda
  generates: {
    "src/generated/graphql.ts": {
      plugins: [
        "typescript",
        "typescript-operations",
        "typescript-react-apollo" // Atau "typescript-react-query" dll.
      ],
      config: {
        withHooks: true,
      }
    }
  }
};

export default config;

Jalankan graphql-codegen (biasanya npm run generate setelah dikonfigurasi di package.json). Hasilnya adalah file src/generated/graphql.ts yang berisi:

// src/generated/graphql.ts (contoh hasil generate)
import { gql } from '@apollo/client';
import * as Apollo from '@apollo/client';
export type GetUsersQueryVariables = Exact<{ [key: string]: never; }>;
export type GetUsersQuery = { __typename?: 'Query', users: Array<{ __typename?: 'User', id: string, name: string, email: string }> };

export const GetUsersDocument = gql`
    query GetUsers {
      users {
        id
        name
        email
      }
    }
`;

export function useGetUsersQuery(baseOptions?: Apollo.QueryHookOptions<GetUsersQuery, GetUsersQueryVariables>) {
  const options = { ...baseOptions };
  return Apollo.useQuery<GetUsersQuery, GetUsersQueryVariables>(GetUsersDocument, options);
}

export type GetUsersHookResult = ReturnType<typeof useGetUsersQuery>;
export type GetUsersQueryResult = Apollo.QueryResult<GetUsersQuery, GetUsersQueryVariables>;

Manfaat: Anda bisa langsung menggunakan useGetUsersQuery() di komponen React Anda, dan data yang dikembalikan akan memiliki tipe yang tepat (GetUsersQuery), tanpa perlu menulis interface atau hook secara manual.

4.2. Code Generation untuk Backend

Di backend GraphQL (misalnya dengan Node.js dan Apollo Server), code generation dapat membantu menghasilkan:

Ini memastikan implementasi resolver Anda selalu sesuai dengan skema GraphQL yang Anda definisikan.

5. Integrasi ke Workflow Pengembangan Anda

Untuk mendapatkan manfaat maksimal, code generation harus diintegrasikan dengan mulus ke dalam siklus pengembangan Anda.

🎯 Strategi Integrasi:

  1. Sebagai Git Hook (Pre-commit):

    • Jalankan perintah generate sebelum setiap commit. Jika ada perubahan skema yang menghasilkan perubahan kode, kode yang digenerate akan ikut ter-commit.
    • ⚠️ Perhatian: Ini bisa memperlambat commit jika proses generate memakan waktu.
  2. Sebagai Bagian dari Script Build/Dev:

    • Jalankan generator setiap kali Anda memulai server pengembangan atau sebelum build produksi.
    • Contoh di package.json:
      "scripts": {
        "dev": "npm run generate && react-scripts start",
        "build": "npm run generate && react-scripts build",
        "generate": "openapi-typescript-codegen --input ./openapi.yaml --output ./src/api --client axios"
      }
  3. Di Pipeline CI/CD:

    • Paling penting, jalankan code generation di CI/CD Anda. Jika ada perubahan skema yang menghasilkan kode baru, pastikan kode tersebut digenerate dan di-commit. Atau, Anda bisa membuat langkah CI yang memverifikasi bahwa kode yang digenerate di repo sudah up-to-date dengan skema. Jika tidak, build gagal, memaksa developer untuk generate dan commit ulang.
    • Ini menjamin konsistensi antara skema dan kode yang dideploy.

6. Manfaat Nyata di Proyek Anda

Penerapan code generation dari skema API membawa dampak signifikan pada proyek full-stack Anda:

Kesimpulan

Code generation dari skema API seperti OpenAPI dan GraphQL bukanlah sekadar ‘nice-to-have’, melainkan sebuah praktik esensial untuk pengembangan full-stack modern. Ini adalah investasi kecil di awal yang akan membayar dividen besar dalam bentuk konsistensi, produktivitas, kualitas kode, dan pengalaman developer yang jauh lebih baik. Dengan mengadopsi pendekatan schema-driven, Anda membangun fondasi yang kokoh untuk aplikasi yang lebih skalabel, mudah dirawat, dan bebas bug.

Jadi, tunggu apa lagi? Mulailah eksplorasi tool code generation dan integrasikan ke dalam workflow Anda. Ucapkan selamat tinggal pada boilerplate yang membosankan dan sambut era pengembangan yang lebih cerdas dan efisien!

🔗 Baca Juga