Tutorial Menggunakan GraphQL Pada Node JS - CRUDPRO

Tutorial Menggunakan GraphQL Pada Node JS

Tutorial Menggunakan GraphQL Pada Node JS

Pada panduan kali ini, sebuah project aplikasi GraphQL dibuat. Aplikasi GraphQL yang akan dibuat ialah sebuah aplikasi untuk mengelola data buku.

Struktur Project

Project aplikasi yang dibuat menggunakan repository pattern. Pattern ini dipakai supaya proses perubahan atau pembaruan code jadi lebih gampang dilakukan dan membuat code yang dicatat jadi lebih rapi. Berikut contoh dari repository pattern yang dipakai.

Tutorial Menggunakan GraphQL Pada Node JS

Pada gambar tersebut, terdapat tiga komponen:

  • Repository: Untuk melakukan komunikasi dengan storage, storage saat ini berupa array biasa (nanti diimplementasikan dengan MySQL).
  • Service: Untuk menggunakan method dari repository dan sebagai perantara antara repository dengan resolver.
  • Resolver: Untuk menggunakan method dari service. Resolver berfungsi untuk menjalankan sebuah proses jika query atau mutation digunakan.
Proyek telah dibuat sebelumnya di tutorial bagian 1.

Menambahkan Data Buku

Sebuah library uuid ditambahkan untuk membuat ID dari data buku.

npm install --save uuid

Sebuah schema untuk menambahkan data buku dibuat di dalam file schema.js di dalam folder graphql.

const { buildSchema } = require("graphql");

module.exports = buildSchema(`
type Book {
  id: ID!
  title: String!
  author: String!
  isRead: Boolean!
}

input BookInputData {
  title: String!
  author: String!
  isRead: Boolean!
}

type RootQuery {
  book: Book!
}
 
type RootMutation {
  addBook(bookInput: BookInputData!): Book!
}

schema {
  query: RootQuery
  mutation: RootMutation
}
`);

Pada schema itu, struktur data untuk data buku dibuat pada type Book. struktur data yang dipakai untuk menambah data buku dibuat pada input BookInputData yang terbagi dalam judul, author dan isRead. Sebuah mutation dibuat yakni addBook yang dipertambah dalam RootMutation.

Membuat mode untuk menyimpan data buku pada file model.js dalam folder model.

// membuat storage untuk menyimpan data buku
const books = [];

// melakukan ekspor storage
module.exports = books;

Membuat repository untuk menambah data buku ke penyimpanan berbentuk array. Komponen repository dibuat dalam file repository.js dalam folder repository.

// mengimpor storage dari model
const books = require("../model/model");

// membuat repository
class BookRepository {
  // membuat method untuk menambahkan data buku
  static addBook(data) {
    // menambahkan data dengan method push()
    books.push(data);
    // mengembalikan data buku yang ditambahkan
    return data;
  }
}

// melakukan ekspor repository yang telah dibuat
module.exports = BookRepository;

Membuat servis untuk memakai metode dari repository. Elemen servis dibuat dalam file servis.js dalam folder servis.

// mengimpor repository
const BookRepository = require("../repository/repository");

// membuat service
class BookService {
  // membuat method untuk menambahkan data
  static addBook(data) {
    // menambahkan data dengan
    // memanggil method addBook dari repository
    return BookRepository.addBook(data);
  }
}

// melakukan ekspor service yang telah dibuat
module.exports = BookService;

Membuat resolver untuk memakai metode dari servis. Sebuah resolver dibuat dalam file resolver.js di dalam folder graphql.

// mengimpor library uuidv4 untuk membuat ID
const { v4: uuidv4 } = require("uuid");

// mengimpor service
const BookService = require("../service/service");

// membuat fungsi untuk resolver
module.exports = {
  // membuat resolver untuk mutation addBook
  addBook: ({ bookInput }) => {
    // mengambil input
    const createdBook = {
      id: uuidv4(),
      title: bookInput.title,
      author: bookInput.author,
      isRead: bookInput.isRead,
    };

    // menambahkan data buku dengan method addBook()
    const result = BookService.addBook(createdBook);

    // mengembalikan hasil penambahan data buku
    return result;
  },
};

Memakai schema dan resolver yang sudah dibuat pada server dalam file server.js.

const express = require("express");
const { graphqlHTTP } = require("express-graphql");

// mengimpor schema yang telah dibuat
const graphqlSchema = require("./graphql/schema");
// mengimpor resolver yang telah dibuat
const graphqlResolver = require("./graphql/resolver");

const app = express();

app.use(
  "/graphql",
  graphqlHTTP({
    // menggunakan schema
    schema: graphqlSchema,
    // menggunakan resolver
    rootValue: graphqlResolver,
    graphiql: true,
  })
);

app.listen(5000, () => {
  console.log("server started!");
});

Lakukan server dengan command npm start lalu membuka web browser dan akses halaman localhost:5000/graphql.

Coba tambahkan data buku dengan query ini.

mutation {
  addBook(bookInput: {title: "Data Structure", author: "joe", isRead: false}) {
    id
    title
    author
  }
}mutation {
  addBook(bookInput: {title: "Data Structure", author: "joe", isRead: false}) {
    id
    title
    author
  }
}

Hasil query.

{
  "data": {
    "addBook": {
      "id": "37362bb0-a4e7-4bfa-bd8d-7c618140fb34",
      "title": "Data Structure",
      "author": "joe"
    }
  }
}

Berdasarkan hasil query tersebut, data buku berhasil ditambahkan.

Mendapatkan Seluruh Data Buku

Sebuah schema query untuk mendapatkan seluruh data buku ditambahkan dalam schema.js.

type RootQuery {
  books: [Book!]!
}

Berdasar schema itu, notasi [] dipakai untuk mengisyaratkan jika data yang dibalikkan berbentuk beberapa kumpulan data dalam jumlah yang banyak.

Code lengkap dari schema.js.

const { buildSchema } = require("graphql");

module.exports = buildSchema(`
type Book {
  id: ID!
  title: String!
  author: String!
  isRead: Boolean!
}

input BookInputData {
  title: String!
  author: String!
  isRead: Boolean!
}

type RootQuery {
  books: [Book!]!
}
 
type RootMutation {
  addBook(bookInput: BookInputData!): Book!
}

schema {
  query: RootQuery
  mutation: RootMutation
}
`);

Menambahkan method untuk mendapatkan seluruh data buku pada repository.js.

// membuat method untuk mendapatkan seluruh data buku
static getBooks() {
    return books;
}

Kode lengkap repository.js.

const books = require("../model/model");

class BookRepository {
  static addBook(data) {
    books.push(data);
    return data;
  }

  static getBooks() {
    return books;
  }
}

module.exports = BookRepository;

Menggunakan method agar mendapatkan seluruh data buku dari repository pada service.js.

// membuat method untuk mendapatkan seluruh data buku
static getBooks() {
    return BookRepository.getBooks();
}

Kode lengkap service.js.

const BookRepository = require("../repository/repository");

class BookService {
  static addBook(data) {
    return BookRepository.addBook(data);
  }

  static getBooks() {
    return BookRepository.getBooks();
  }
}

module.exports = BookService;

Menggunakan method untuk mendapatkan seluruh data buku dari service pada resolver.js.

module.exports = {
  // kode lain..

  // membuat resolver untuk query books
  books: () => {
    // mendapatkan seluruh data buku dengan method getBooks()
    return BookService.getBooks();
  },
};

Kode lengkap resolver.js.

const { v4: uuidv4 } = require("uuid");

const BookService = require("../service/service");

module.exports = {
  addBook: ({ bookInput }) => {
    const createdBook = {
      id: uuidv4(),
      title: bookInput.title,
      author: bookInput.author,
      isRead: bookInput.isRead,
    };

    const result = BookService.addBook(createdBook);

    return result;
  },

  books: () => {
    return BookService.getBooks();
  },
};

Lakukan server dengan command npm start lalu membuka web browser dan akses halaman localhost:5000/graphql.

Menambahkan berbagai data buku.

mutation {
  addBook(bookInput:{title:"Data Structure",author:"joe",isRead:false}) {
    id
    title
  }
}
mutation {
  addBook(bookInput:{title:"Algorithm",author:"zoe",isRead:false}) {
    id
    title
  }
}

Mendapatkan seluruh data buku dengan query berikut. Kata kunci query dapat dihapus.

{
  books {
    id
    title
    author
  }
}

Hasil query.

{
  "data": {
    "books": [
      {
        "id": "1ec527db-2b29-419f-b133-6c02c33a9226",
        "title": "Data Structure",
        "author": "joe"
      },
      {
        "id": "249b431b-e60f-41ef-bcc8-20269eab00c5",
        "title": "Algorithm",
        "author": "zoe"
      }
    ]
  }
}

Berdasar hasil query, semua data buku berhasil didapatkan. Atribut data buku berbentuk id, judul dan nama penulis diperlihatkan.

Memperoleh Data Buku Tertentu

Sebuah schema query untuk memperoleh data buku tertentu berdasar ID dibuat dalam schema.js.

book(id: ID!): Book!

Kode lengkap schema.js.

const { buildSchema } = require("graphql");

module.exports = buildSchema(`
type Book {
  id: ID!
  title: String!
  author: String!
  isRead: Boolean!
}

input BookInputData {
  title: String!
  author: String!
  isRead: Boolean!
}

type RootQuery {
  book(id: ID!): Book!
  books: [Book!]!
}
 
type RootMutation {
  addBook(bookInput: BookInputData!): Book!
}

schema {
  query: RootQuery
  mutation: RootMutation
}
`);

Membuat method agar mendapatkan data buku tertentu berdasarkan ID di dalam repository.js.

// membuat method untuk mendapatkan data buku berdasarkan ID
static getBook(id) {
    return books.filter((book) => book.id === id)[0];
}

Kode lengkap repository.js.

const books = require("../model/model");

class BookRepository {
  static addBook(data) {
    books.push(data);
    return data;
  }

  static getBooks() {
    return books;
  }

  static getBook(id) {
    return books.filter((book) => book.id === id)[0];
  }
}

module.exports = BookRepository;

Menggunakan method untuk mendapatkan data buku berdasarkan ID dari repository pada service.js.

// membuat method untuk mendapatkan data buku berdasarkan ID
static getBook(id) {
    return BookRepository.getBook(id);
}

Kode lengkap service.js.

const BookRepository = require("../repository/repository");

class BookService {
  static addBook(data) {
    return BookRepository.addBook(data);
  }

  static getBooks() {
    return BookRepository.getBooks();
  }

  static getBook(id) {
    return BookRepository.getBook(id);
  }
}

module.exports = BookService;

Menggunakan method untuk mendapatkan data buku berdasarkan ID dari service pada resolver.js.

module.exports = {
  // kode lain..

  // membuat resolver untuk query book
  book: ({ id }) => {
    // mendapatkan data buku berdasarkan id dengan method getBook()
    return BookService.getBook(id);
  },
};

Kode lengkap resolver.js.

const { v4: uuidv4 } = require("uuid");

const BookService = require("../service/service");

module.exports = {
  addBook: ({ bookInput }) => {
    const createdBook = {
      id: uuidv4(),
      title: bookInput.title,
      author: bookInput.author,
      isRead: bookInput.isRead,
    };

    const result = BookService.addBook(createdBook);

    return result;
  },

  books: () => {
    return BookService.getBooks();
  },

  book: ({ id }) => {
    return BookService.getBook(id);
  },
};

Menambahkan beragam data buku.

mutation {
  addBook(bookInput:{title:"Data Structure",author:"joe",isRead:false}) {
    id
    title
  }
}
mutation {
  addBook(bookInput:{title:"Algorithm",author:"zoe",isRead:false}) {
    id
    title
  }
}

Mendapatkan data buku berdasarkan ID.

{
  book(id: "e5de0fef-8afd-4100-a484-bc554bcaac4c") {
    title
    author
  }
}

Hasil query.

{
  "data": {
    "book": {
      "title": "Algorithm",
      "author": "zoe"
    }
  }
}

Berdasar hasil query itu, data buku berbentuk judul dan nama penulis ditunjukkan.


Catatan

Semoga artikel ini bermanfaat. Jika terdapat kritik atau saran silahkan tulis di kolom komentar ya!