tutorial

109 Menghubungkan Resolver dengan Model Database

109 Menghubungkan Resolver dengan Model Database: Studi Kasus Praktis

Dalam dunia pengembangan perangkat lunak modern, integrasi antara application layer dan database adalah pondasi dari setiap aplikasi yang scalable dan robust. Salah satu arsitektur yang sedang naik daun adalah GraphQL, yang mengandalkan struktur resolver untuk mengambil atau memodifikasi data dari berbagai sumber—terutama database. Artikel ini akan mengupas bagaimana menghubungkan resolver dengan model database menggunakan contoh konkret, kode, tabel, dan diagram alur menggunakan mermaid.


Pemanasan: Apa Itu Resolver?

Sebelum kita menyelam lebih dalam, mari kita samakan persepsi tentang resolver. Dalam konteks GraphQL, resolver adalah fungsi yang bertanggung jawab menangani permintaan (query atau mutation) dari user, lalu mengambil, memanipulasi, dan mengembalikan data yang sesuai. Biasanya resolver akan berbicara dengan database models untuk mendapatkan data terkini.


Studi Kasus: Sistem Manajemen Buku

Katakanlah kita ingin membuat aplikasi sederhana untuk mengelola koleksi buku. Kita akan menggunakan stack Node.js, Express, Sequelize (ORM untuk PostgreSQL), dan Apollo Server (implementasi GraphQL).

Struktur Model Database

Model Book akan kita definisikan menggunakan Sequelize seperti berikut:

// models/book.js
const { DataTypes } = require('sequelize');
const sequelize = require('../config/database');

const Book = sequelize.define('Book', {
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true,
    autoIncrement: true
  },
  title: {
    type: DataTypes.STRING,
    allowNull: false
  },
  author: DataTypes.STRING,
  published_year: DataTypes.INTEGER
});

module.exports = Book;

Tabel Book:

idtitleauthorpublished_year
1Clean CodeRobert Martin2008
2The Pragmatic ProgrammerAndy Hunt1999

Diagram Alur Interaksi Resolver dan Database

Mari kita visualisasikan apa yang terjadi saat klien meminta data menggunakan query GraphQL dengan diagram mermaid berikut:

sequenceDiagram
  participant Client
  participant Server
  participant Resolver
  participant Database

  Client->>Server: Kirim query GraphQL
  Server->>Resolver: Panggil resolver terkait (misal: books)
  Resolver->>Database: Query daftar buku
  Database-->>Resolver: Kembalikan data buku
  Resolver-->>Server: Kirim hasil data
  Server-->>Client: Kirim respon JSON

Menyusun Resolver

Pada folder resolvers, mari kita buat resolver sederhana yang menghubungkan ke model Book.

// resolvers/bookResolver.js
const Book = require('../models/book');

const bookResolver = {
  Query: {
    books: async () => {
      try {
        const allBooks = await Book.findAll();
        return allBooks;
      } catch (error) {
        throw new Error(`Gagal mengambil data buku: ${error.message}`);
      }
    },
    book: async (_, { id }) => {
      try {
        const book = await Book.findByPk(id);
        if (!book) throw new Error('Buku tidak ditemukan');
        return book;
      } catch (error) {
        throw new Error(`Gagal mengambil data buku: ${error.message}`);
      }
    }
  },
  Mutation: {
    addBook: async (_, { title, author, published_year }) => {
      try {
        const newBook = await Book.create({ title, author, published_year });
        return newBook;
      } catch (error) {
        throw new Error(`Gagal menambah buku: ${error.message}`);
      }
    }
  }
};

module.exports = bookResolver;

Contoh Skema GraphQL

Mari kita hubungkan resolver ini ke skema GraphQL kita:

// schema/typeDefs.js
const { gql } = require('apollo-server-express');

const typeDefs = gql`
  type Book {
    id: ID!
    title: String!
    author: String
    published_year: Int
  }

  type Query {
    books: [Book]
    book(id: ID!): Book
  }

  type Mutation {
    addBook(title: String!, author: String, published_year: Int): Book
  }
`;

module.exports = typeDefs;

Integrasi Resolver & Database Layer

Pada dasarnya, teknik menghubungkan resolver dengan model database adalah sebagai berikut:

Alur Kode:

  1. Query diterima oleh server GraphQL.
  2. Resolver dipanggil sesuai permintaan query atau mutation.
  3. Resolver mengambil data menggunakan metode model ORM (misal: findAll, findByPk, create di Sequelize).
  4. Hasil dikembalikan ke client dalam format JSON.

Simulasi: End-to-End

1. Query Daftar Buku

Permintaan dari client:

query {
  books {
    id
    title
    author
    published_year
  }
}

Hasil respon dari server:

{
  "data": {
    "books": [
      {
        "id": "1",
        "title": "Clean Code",
        "author": "Robert Martin",
        "published_year": 2008
      },
      {
        "id": "2",
        "title": "The Pragmatic Programmer",
        "author": "Andy Hunt",
        "published_year": 1999
      }
    ]
  }
}

2. Menambah Buku Baru

Mutation:

mutation {
  addBook(title: "Refactoring", author: "Martin Fowler", published_year: 1999) {
    id
    title
  }
}

Best Practices dan Catatan

Menghubungkan resolver dengan model database harus dilakukan dengan memperhatikan beberapa best practices berikut:

  1. Error Handling: Selalu tangani error dari layer ORM agar informasi masalah mudah di-debug.
  2. Asynchronous Handling: Gunakan async/await pada resolver untuk menghindari callback hell dan mempermudah debugging.
  3. Separasi Concern: Letakkan logic database di model atau layer service, dan buat resolver tetap ramping.
  4. Optimasi Query: Hindari N+1 problem dengan menggunakan teknik batch atau data loader, terutama untuk relasi many-to-many.

Penutup

Menghubungkan resolver dengan model database adalah step vital dalam membangun aplikasi dengan GraphQL. Dengan praktik yang benar—seperti pada studi kasus di atas—kita bisa membangun API yang scalable, robust, dan mudah dikembangkan. Diagram alur, kode, dan simulasi di atas semoga cukup memberi gambaran nyata bagaimana proses ini berjalan di dunia nyata.

Jika Anda tertarik mengembangkan lebih lanjut, mulai dari authentication, relasi antar tabel, hingga kasus penggunaan yang kompleks, jangan ragu untuk bereksperimen dan membaca dokumentasi lebih lanjut dari ORM maupun framework GraphQL yang Anda gunakan.

Selamat ngoding! 🚀

comments powered by Disqus