tutorial

34 Menyimpan Data ke Database Lewat Mutation

34 Menyimpan Data ke Database Lewat Mutation: Cara Kerja, Studi Kasus, dan Best Practices

Menulis data ke database merupakan salah satu inti dalam pengembangan aplikasi modern, baik itu aplikasi web, mobile, maupun backend service. Salah satu pendekatan populer untuk melakukan operasi write di arsitektur berbasis GraphQL maupun pattern CQRS adalah melalui mutation. Pada artikel kali ini, kita akan membedah cara kerja mutation dalam proses penyimpanan data ke database, dari request masuk hingga commit ke database, lengkap dengan kode simulasi, studi kasus, tabel, dan diagram alur.

Apa itu Mutation?

Mutation adalah salah satu jenis operation dalam GraphQL yang digunakan untuk membuat, mengubah, atau menghapus data (write operation), berbeda dengan query yang khusus untuk proses pembacaan data (read only).

Konsep “mutation” juga kerap digunakan secara lebih umum pada layer services atau API, misal pada REST biasa (POST/PUT/PATCH/DELETE), meskipun istilah umumnya lebih lekat dengan dunia GraphQL.

Diagram Alur: Mutation Menyimpan Data

Mari kita lihat flow umum ketika data ingin disimpan ke database lewat mutation:

sequenceDiagram
  participant Client
  participant API
  participant Service
  participant Database

  Client->>API: Kirim Mutation (data)
  API->>Service: Validasi & Proses Mutation
  Service->>Database: INSERT/UPDATE/DELETE
  Database-->>Service: Response
  Service-->>API: Status/Result
  API-->>Client: Jawaban ke Klien

Studi Kasus: Menyimpan Data User Melalui Mutation

1. Skema Database

Sebagai contoh, kita akan menggunakan skema tabel sederhana berikut pada database users:

idnameemailcreated_at
1Budibudi@email.com2024-06-12 12:30:01
2Sitisiti@email.com2024-06-13 09:21:10

2. Definisi GraphQL Mutation

Mari tentukan mutation GraphQL-nya:

type Mutation {
  createUser(name: String!, email: String!): User!
}

Respon yang diharapkan adalah data user setelah berhasil disimpan.

Type User

type User {
  id: ID!
  name: String!
  email: String!
  createdAt: String!
}

3. Implementasi Resolver Mutation

Anggap kita memakai Node.js dan library seperti Apollo Server serta ORM prisma:

schema.graphql

type Mutation {
  createUser(name: String!, email: String!): User!
}

type User {
  id: ID!
  name: String!
  email: String!
  createdAt: String!
}

resolvers.js

const { PrismaClient } = require('@prisma/client');
const prisma = new PrismaClient();

const resolvers = {
  Mutation: {
    async createUser(_, { name, email }) {
      // Validasi sederhana, pastikan email unik
      const existing = await prisma.user.findUnique({ where: { email } });
      if (existing) {
        throw new Error("Email sudah terdaftar!");
      }

      const user = await prisma.user.create({
        data: { name, email },
      });

      return user;
    },
  },
};

module.exports = resolvers;

Pada code di atas, perhatikan titik penting mutation:

  1. Validasi Input:
    • Tidak boleh kosong, email harus unik
  2. Proses Insert:
    • Panggil database lewat ORM (prisma) untuk membuat entri baru
  3. Kirim Response:
    • Kirim data user yang baru dimasukkan

4. Menggunakan Mutation dari Client

Misal ingin menambahkan user baru lewat mutation:

mutation {
  createUser(name: "Andi", email: "andi@email.com") {
    id
    name
    email
    createdAt
  }
}

Response JSON

{
  "data": {
    "createUser": {
      "id": "3",
      "name": "Andi",
      "email": "andi@email.com",
      "createdAt": "2024-06-14T10:15:30Z"
    }
  }
}

Simulasi: Pipeline Mutation ke Database

Untuk memperjelas prosesnya, simulasikan flow mutation hingga ke database:

  1. Client (Web/mobile) mengirim request mutation ke endpoint GraphQL.
  2. API Gateway menerima dan meneruskan ke GraphQL server.
  3. GraphQL Server menjalankan resolver createUser.
  4. Resolver melakukan validasi, transformasi, lalu commit ke database melalui ORM.
  5. Database melakukan insert baru pada tabel user.
  6. GraphQL Server membungkus hasil (atau error jika gagal) ke response.
  7. Client menerima response dan mengupdate state.
flowchart TB
    subgraph Client Side
      A[User mengisi form nama/email]
      B[Klik tombol Submit]
      C[Mutation HTTP request ke API]
    end

    subgraph Server Side
      D[API menerima request]
      E[Resolver memproses: Validasi]
      F[Tulis ke Database via ORM]
      G[Sukses: Kirim objek user baru ke klien]
      H[Gagal: Kirim pesan error]
    end

    A --> B --> C --> D --> E
    E --> F
    F --> G
    E --> H

Teknik Validasi Untuk Menjaga Integritas Data

Menulis data tanpa validasi sama saja membuka peluang error dan korupsi data. Berikut beberapa teknik validasi yang wajib:

  • Validasi Required: Pastikan input tidak kosong.
  • Email Unik: Cek ke database sebelum insert.
  • Format Email: Pakai regex untuk memastikan formatnya benar.
  • Rate Limiting: Batasi frekuensi mutation supaya tidak flooding.

Performance Tips: Mutation Batch & Transaction

Mutation umumnya bersifat synchronous, namun untuk kasus heavy load, bisa dijalankan dalam batch (bulk insert) atau transaction (multi step):

Bulk Insert Example

const users = [
  { name: "John", email: "john@email.com" },
  { name: "Jane", email: "jane@email.com" }
];

// prisma.$transaction mendukung batch insert agar atomic
await prisma.$transaction([
  prisma.user.createMany({ data: users })
]);

Transaction pada Update Serentak

await prisma.$transaction(async (prisma) => {
  await prisma.user.update({ ... });
  await prisma.activityLog.create({ ... });
});

Tabel Error Dan Response Mutation

KondisiResponseHTTP Status
Sukses input userData user yang baru200
Email sudah digunakanError: Email sudah terdaftar400
Format email salahError: Email format tidak valid400
Database connection errorError: Internal Server Error500

Best Practices Menyimpan Data via Mutation

Berikut beberapa best practice dalam implementasi mutation menyimpan data ke database:

  1. Selalu Validasi Input sebelum menulis ke database.
  2. Tangani Error dengan baik, berikan response yang informatif.
  3. Gunakan Transaction untuk operasi yang saling terkait.
  4. Minimalkan Batasan Unik di Database — validasi di aplikasi juga tidak cukup jika ada race condition, gunakan unique constraint (ex: unique index pada kolom email).
  5. Jangan expose field-field sensitif (seperti hash password) ke response.
  6. Log setiap mutation sebagai audit trail.

Penutup

Mutation adalah jembatan utama dalam arsitektur modern antara user/client dan database. Dengan desain yang baik, validasi yang ketat, dan penanganan error yang matang, Anda dapat memastikan proses penyimpanan data lewat mutation bukan hanya efisien, tapi juga aman dan maintainable.

Di sisi aplikasi, mutation perlu dipadukan dengan praktik seperti batching, transaction, serta API rate limiting untuk menghadirkan system yang robust di production. Semoga penjelasan dan contoh kode di atas bisa memperjelas bagaimana alur menyimpan data ke database secara efektif lewat mutation. Selamat mencoba — dan pastikan setiap write operation Anda aman! 🚀


Silakan tinggalkan komentar atau diskusi bila rekan-rekan ingin lebih dalam membahas topik mutation, transactional write, atau security pattern di API modern!

comments powered by Disqus

Topik Terhangat

programming
245
tutorial
112
tips-and-trick
43
jaringan
28
hardware
11
linux
4
kubernetes
1