65 Skema Dinamis dan Custom Scalar Types: Menjelajah Dunia Type System yang Lebih Fleksibel
Dalam dunia modern pengembangan perangkat lunak, API tidak hanya sekadar jembatan antar sistem, tapi juga kontrak yang menentukan cara data dipertukarkan. Salah satu pilar utama dalam mendefinisikan API, khususnya dalam konteks GraphQL atau gRPC, adalah type system. Artikel ini akan mengupas dua aspek advanced yakni skema dinamis dan custom scalar types. Kita akan melihat alasan, implementasi, serta contoh pragmatis penggunaan keduanya.
Mengapa Skema Dinamis?
Pada banyak kasus, kebutuhan bisnis dapat berubah dengan cepat. Jika sebuah API memaksa struktur data yang kaku (rigid) dan sulit beradaptasi, maka perubahan-perubahan kecil pun bisa berujung pada deployment besar-besaran. Maka dari itu, muncul konsep skema dinamis—di mana struktur data bisa disesuaikan atau bahkan didefinisikan oleh pengguna API tanpa harus melakukan hardcode di tingkat kode sumber.
Skema Dinamis membuat API menjadi:
- Lebih mudah beradaptasi
- Minim downtime karena deploy schema baru
- Mendukung use-case custom/sesuai kebutuhan
Contoh Skenario Skema Dinamis
Bayangkan aplikasi SaaS yang menawarkan penyimpanan data custom untuk tiap client. Setiap tenant ingin menyimpan data dengan struktur yang berbeda (misal: HR, Inventory, atau CRM). Akan sangat memberatkan jika kita harus membuat schema baru untuk setiap tenant.
Sekilas Custom Scalar Types
Tipe data scalar adalah tipe paling dasar seperti Int
, Float
, String
, dst. Namun, kadang tipe data bisnis jauh lebih kaya, dan menggunakan tipe dasar bisa membuka risiko data tidak valid, misal: menyimpan email
sebagai String
.
Di sinilah custom scalar types berperan:
- Membuat codebase lebih type safe
- Menyederhanakan validasi di sisi backend
- Dokumentasi API jadi lebih jelas
Simulasi: Dynamic Schema & Custom Scalar di GraphQL
Mari masuk ke contoh nyata! Kita akan menggunakan GraphQL yang memang sangat flexible baik dalam mendefinisikan schema secara dinamis maupun mendukung custom scalar types.
1. Membuat Custom Scalar Type
Misal, aplikasi kita butuh validasi khusus untuk tipe PhoneNumber
.
// src/schema/scalars.js
const { GraphQLScalarType, Kind } = require('graphql');
const PhoneNumber = new GraphQLScalarType({
name: 'PhoneNumber',
description: 'Custom Phone Number Scalar',
serialize(value) {
return value; // Asumsi value sudah berbentuk string valid
},
parseValue(value) {
if (!/^\+628[0-9]{8,}$/.test(value)) {
throw new Error('Invalid phone number. Must start with +628');
}
return value;
},
parseLiteral(ast) {
if (ast.kind === Kind.STRING && /^\+628[0-9]{8,}$/.test(ast.value)) {
return ast.value;
}
throw new Error('Invalid phone number');
},
});
module.exports = { PhoneNumber };
Dengan cara ini, field yang bertipe PhoneNumber
akan selalu tervalidasi.
2. Definisi Skema Dinamis
GraphQL biasanya menggunakan schema statis, tapi ada strategi agar schema bisa berubah di runtime:
Implementasi Skema Dinamis
Katakan, client boleh menentukan sendiri field apa yang ingin disimpan di objek Customer
. Contoh:
// src/schema/dynamicSchema.js
const {
GraphQLObjectType,
GraphQLSchema,
GraphQLString,
GraphQLScalarType
} = require('graphql');
// Dynamic function generates new fields:
function generateCustomerType(fieldDefinitions) {
const fields = {};
fieldDefinitions.forEach(def => {
fields[def.name] = { type: GraphQLString, description: def.desc };
});
return new GraphQLObjectType({
name: 'Customer',
fields,
});
}
const dynamicFieldDefinitions = [
{ name: 'firstName', desc: 'Nama Depan Pelanggan' },
{ name: 'lastName', desc: 'Nama Belakang Pelanggan' },
{ name: 'phone', desc: 'Nomor Telepon', type: 'PhoneNumber' },
];
const CustomerType = generateCustomerType(dynamicFieldDefinitions);
const QueryType = new GraphQLObjectType({
name: 'Query',
fields: {
customer: {
type: CustomerType,
resolve: () => ({ firstName: 'Ahmad', lastName: 'Yani', phone: '+62812345678' }),
}
}
});
const schema = new GraphQLSchema({ query: QueryType });
module.exports = { schema };
Dengan pendekatan ini, struktur Customer
dapat berubah cukup dengan mengubah array dynamicFieldDefinitions
, tidak perlu mengubah kode schema secara manual.
Kelebihan & Tantangan
Kelebihan | Tantangan |
---|---|
Sangat fleksibel, cepat adaptasi | Meningkatkan risiko runtime error |
Mendukung multi-tenant / custom data | Lebih sulit divalidasi secara static |
Validasi lebih baik via custom scalar | Risk data leaky tanpa schema ketat |
Schema bisa diubah tanpa re-deploy | Code semakin kompleks |
Diagram Alur: Proses Pembuatan Skema Dinamis
flowchart TD A[Inisiasi aplikasi] --> B{Ada perubahan struktur data?} B -- "Ya" --> C[Muat/Generate Field Definitions dari DB/config] B -- "Tidak" --> D[Gunakan Schema yang sudah ada] C --> E[Bangun ulang GraphQL Schema di runtime] E --> F[Jalankan API Server] D --> F
Studi Kasus: Multi-Tenant SaaS
Sebuah SaaS ingin setiap tenant bisa mengkostumisasi field Lead
. Tenant A ingin leadStatus
, tenant B ingin industry
& budget
. Dengan dynamic schema generator, admin dapat menetapkan field mana saja yang mau digunakan:
Contoh Konfigurasi Tenant:
Tenant | Field | Type |
---|---|---|
Alpha | leadStatus | String |
Beta | industry | String |
Beta | budget | Int |
Gamma | phone | PhoneNumber |
Mekanisme generate schema sesuai table/DB konfigurasi.
Best Practice & Tips
- Simpan definisi schema dinamis di luar kode (DB/file store), jangan hardcode.
- Custom scalar harus didukung baik di client dan server, misal via dokumentasi.
- Selalu logging error runtime schema untuk mencegah silent bug.
- Gunakan generator/type-factory agar pembuatan schema tetap DRY.
- Jika scalable, cache schema hasil generate agar startup lebih cepat.
Penutup
Dengan menerapkan skema dinamis dan custom scalar types, arsitektur aplikasi API Anda menjadi jauh lebih adaptif, mudah berkembang, serta lebih robust dari sisi keamanan data. Namun, fleksibilitas ekstra ini datang dengan trade-off berupa peningkatan kompleksitas dan risiko error runtime yang harus dikelola dengan baik.
Dengan desain dan implementasi yang hati-hati, kedua konsep ini bisa menjadi pembeda utama antara produk SaaS atau API yang skalabel versus yang mudah deadlock perubahan.
Seperti biasa, kunci utama adalah eksperimen dan review: jangan ragu mencoba, tapi disiplin dalam validasi dan monitoring.
Selamat membangun API masa depan! 🚀
87. Studi Kasus: Debugging Masalah Streaming
Artikel Terhangat
66 Pengenalan Federated GraphQL Architecture
09 Sep 2025
65 Skema Dinamis dan Custom Scalar Types
09 Sep 2025
87. Studi Kasus: Debugging Masalah Streaming
09 Sep 2025
64 Aliases dan Directives di Query
09 Sep 2025
63 Fragment GraphQL dan Implementasinya
09 Sep 2025
85. Logging dan Debugging dengan `grpc-go`
09 Sep 2025

66 Pengenalan Federated GraphQL Architecture

65 Skema Dinamis dan Custom Scalar Types

87. Studi Kasus: Debugging Masalah Streaming

64 Aliases dan Directives di Query

63 Fragment GraphQL dan Implementasinya
