Exploring

Area Bahasan:

  • Apa itu GraphQL
  • Kenapa harus GraphQL
  • Perbedaan GraphQL  dengan REST
  • Konsep dan arsitektur GraphQL
  • Ekosistem dan sarana GraphQL
  • Implementasi di sisi frontend / client

Apa itu GraphQL ?

GraphQL adalah spesifikasi dan bahasa query untuk API (Application Programming Interface).
  • Bukan database
  • Tidak spesifik ke satu bahasa program
  • Bukan Library / Pustaka
  • Bukan Produk
  • Efisien dan alternatif REST (REpresentational State Transfer)

Kenapa GraphQL

GraphQL ada karena kebutuhan akan  performa, fleksibilitas dan efisiensi yang lebih baik disisi komunikasi antara client dan server.
Masalah apa yang ingin GraphQL pecahkan?

Kenapa GraphQL

Buat tampilan di web atau mobile app informasi kursus.

Contoh kasus:

Tampilkan:

  • Topik workshop
  • Jadwal workshop
  • Lokasi workshop
  • Pengajar workshop
  • Para peserta yang mengikuti workshop

Kenapa GraphQL

Cara request REST
api/course/:id
api/course/:id/location
api/course/:id/teacher
api/course/:id/students
RESTFul API server

Kenapa GraphQL

response REST untuk kursus
{
  "course": {
    "id": 1,
    "title": "Flutter for beginner",
    "description": "bla bla bla bla",
    "startedDate": "2020-09-06",
    "endDate": "2020-09-06",
    "startTime": "09:00:00",
    "endTime": "16:00:00",
    "createdAt": "2020-09-01",
    ...
  }
}
api/course/:id
JSON
JSON 
RESTFul API server

Kenapa GraphQL

response REST untuk lokasi
{
  "location": {
    "id": 1,
    "name": "Rumah Coding",
    "address": "Beverly Hills Street",
    "longitude": "-28319487",
    "latitude": "32989475",
    "createdAt": "2020-09-01",
    ...
  }
}
api/course/:id/location
JSON
JSON 
RESTFul API server

Kenapa GraphQL

response REST untuk pengajar
{
  "teacher": {
    "id": 1,
    "name": "John Wick",
    "address": "Beverly Hills Street",
    "birthday": "1999-07-08",
    "skill": "Assasination",
    "createdAt": "2020-09-01",
    ...
  }
}
api/course/:id/teacher
JSON
JSON 
RESTFul API server

Kenapa GraphQL

response REST untuk para peserta
{
  "students": [
     {
      "id": 1,
      "name": "Lutfi Anjay",
      "address": "Anjay Jalan-jalan",
      "birthday": "1999-07-08",
      "membership": "annual",
      "createdAt": "2020-09-01",
      ...
    },
    {
      "id": 2,
      "name": "Ciwi Mili",
      "address": "Jalan-jalan mili",
      "birthday": "2004-07-08",
      "membership": "one-time",
      "createdAt": "2020-09-01",
      ...
    }
  ]
}
api/course/:id/students
JSON
JSON 
RESTFul API server

Kenapa GraphQL

request GraphQL
{
  courseEvent(id: "uuid") {
    course {
      name
      description
    }
    startDate
    startTime
    endDate
    endTime
    location {
      name
      address
      latitude
      longitude
    }
    teacher {
      name
      skill
    }
    students(first: 10) {
      name
    }
  }
}
query
GraphQL Server
Hanya Sekali request

Kenapa GraphQL

response GraphQL Query
{
  "data": {
    "course": {
      "name": "GraphQL cool",
      "description": "blabla blabla blabla"
    },
    "startDate": "2020-09-06",
    "startTime": "09:00:00+00",
    "endDate": "2020-09-06",
    "endTime": "16:00:00+00",
    "location": {
      "name": "Rumah Coding",
      "address": "Jalan Jalan",
      "latitude": -6.407424,
      "longitude": 106.814019
    },
    "teacher": {
      "name": "Nanda Rizky",
      "skill": "Google Developer Expert"
    },
    "students": [
      {
        "name": "Blaise Renner"
      },
      {
        "name": "Keven Hagenes"
      }
    ]
  }
}
query
JSON
JSON 
GraphQL Server
respon data sesuai yang diminta

Kenapa GraphQL

respon data sesuai yang diminta
{
  "data": {
    "course": {
      "name": "GraphQL cool",
      "description": "blabla blabla blabla"
    },
    "startDate": "2020-09-06",
    "startTime": "09:00:00+00",
    "endDate": "2020-09-06",
    "endTime": "16:00:00+00",
    "location": {
      "name": "Rumah Coding",
      "address": "Jalan Jalan",
      "latitude": -6.407424,
      "longitude": 106.814019
    },
    "teacher": {
      "name": "Nanda Rizky",
      "skill": "Google Developer Expert"
    },
    "students": [
      {
        "name": "Blaise Renner"
      },
      {
        "name": "Keven Hagenes"
      }
    ]
  }
}
response
{
  courseEvent(id: "uuid") {
    course {
      name
      description
    }
    startDate
    startTime
    endDate
    endTime
    location {
      name
      address
      latitude
      longitude
    }
    teacher {
      name
      skill
    }
    students(first: 10) {
      name
    }
  }
}

Kenapa GraphQL

  • Memberikan hak penuh kepada sisi client untuk menentukan data apa yang dibutuhkan, tidak lebih dan tidak kurang
  • GraphQL API butuh hanya satu request untuk mengambil data yang dibutuhkan
  • Respon data tidak balapan (async)

Yang menarik dari ilustrasi tadi:

Perbedaan GraphQL - REST

REST

GRAPHQL

Multiple request bolak-balik untuk mengambil informasi dari multiple resources 
1 Singel request untuk mengambil informasi dari hasil pengumpulan data (aggregation) 
Over Fetching dan Under Fetching data resources
data sesuai dengan permintaan. cukup buat query
Frontend team sangat tergantung pada backend team untuk deliver App
Frontend dan backend team bisa bekerja secara independent
Implementasi Caching dibuat disisi HTTP Spec
Tidak menggunakan HTTP spec untuk caching. Pustaka seperti Relay atau Apollo  mendukung opsi caching 
sisi client tidak tahu data apa yang di berikan oleh server. Bisa tidak konsisten
Ada kontrak antara server dan client melalui schema. Ketat dan lebih konsisten
Sangat lekat HTTP resources / verbs semantic (GET, POST, PUT, DELETE)
Hanya HTTP POST

Perbedaan GraphQL - REST

REST API adalah konsep arsitektur untuk perangkat lunak berbasis jaringan. GraphQL, di sisi lain, adalah bahasa kueri, spesifikasi, dan seperangkat alat yang beroperasi melalui satu titik akhir menggunakan HTTP
Inti perbedaan:

Konsep dan Arsitektur GraphQL

  • Bahasa dengan tipe data yang ketat
  • Punya Tipe data utama yang di sebut Scalar Type
  • Setiap GraphQL punya schema type yang terdiri dari 2 type, yaitu mutation type dan query type  
Karena GraphQL itu bahasa kueri:

Konsep dan Arsitektur GraphQL

  • Int - 32-bit integer

  • Float - double-precision floating point value

  • String - UTF-8 character sequence

  • Boolean - true or false value

  • ID - Unique Identifier, Di gunakan saat re-fetch atau sebagai key untuk caching 

Scalar Type:

Konsep dan Arsitektur GraphQL

Contoh membuat Type dari Scalar Type:
Type Course {
  id: ID
  name: String
  description: String
  rating: Float
  numberOfReviews: Int
  createdAt: String
  updatedAt: String
}
Disebut GraphQL Object Type

Konsep dan Arsitektur GraphQL

Non-Nullable Type
Type Course {
  id: ID!
  name: String!
  description: String
  rating: Float
  numberOfReviews: Int
  createdAt: String
  updatedAt: String
}
By default setiap scalar type bisa di set ke null
Untuk membuat itu wajib
(required) hanya perlu
menambahkan "!" dibelakangnya

Konsep dan Arsitektur GraphQL

Query And Mutation Type
schema {
  query: Query
  mutation: Mutation
}
2 tipe inilah sebagai root / top (entry) level di schema GraphQL
  • Setiap GraphQL selalu punya query Type
  • Bisa tanpa mutation Type
  • Query dan Mutation Type itu hanya definisi GraphQL Object Type

Konsep dan Arsitektur GraphQL

Query And Mutation Type
type Query {
  courses: [CourseType!]
}

type Mutation {
  createEvent(name: String!, description: String): CourseType
}

Konsep dan Arsitektur GraphQL

Query
Fields
{
  students_connection {
    edges {
      node {
        id
        name
        birthday
      }
    }
  }
}

Konsep dan Arsitektur GraphQL

Query
{
  students_connection(first: 3) {
    edges {
      cursor
      node {
        id
        name
        birthday
      }
    }
  }
}
Fields
Arguments

Konsep dan Arsitektur GraphQL

Query
{
  students_connection(first: 3) {
    edges {
      cursor
      node {
        id
        name
        birthday
      }
    }
  }
  students: students_connection(last: 2) {
    edges {
      cursor
      node {
        id
        name
        birthday
      }
    }
  }
}
Fields
Arguments
Alias

Konsep dan Arsitektur GraphQL

Query
{
  students_connection(first: 3) {
    ...studentsConnectionFragment
  }
  students: students_connection(last: 2) {
    ...studentsConnectionFragment
  }
}

fragment studentsConnectionFragment on studentsConnection {
  edges {
    cursor
    node {
      birthday
      id
      name
      publicId
    }
  }
}
Fields
Arguments
Alias
Fragment

Konsep dan Arsitektur GraphQL

Query
fragment studentsFragment on students {
  birthday
  id
  name
  publicId
}

{
  students_connection(first: 3) {
    edges {
      cursor
      node {
        ...studentsFragment
      }
    }
  }
  students: students_connection(last: 2) {
    edges {
      cursor
      node {
        ...studentsFragment
      }
    }
  }
}
Fields
Arguments
Alias
Fragment

Konsep dan Arsitektur GraphQL

Query
query RootQuery {
  students_connection(first: 3) {
    edges {
      cursor
      node {
        ...studentsFragment
      }
    }
  }
  students: students_connection(last: 2) {
    edges {
      cursor
      node {
        ...studentsFragment
      }
    }
  }
}
Fields
Arguments
Alias
Fragment
Operation
name

Konsep dan Arsitektur GraphQL

Query
query RootQuery($first: Int, $last: Int) {
  students_connection(first: $first) {
    edges {
      cursor
      node {
        ...studentsFragment
      }
    }
  }
  students: students_connection(last: $last) {
    edges {
      cursor
      node {
        ...studentsFragment
      }
    }
  }
}
Fields
Arguments
Alias
Fragment
Operation
name
Variable

Konsep dan Arsitektur GraphQL

Mutation
mutation {
  insertStudent(objects: {name: "Jon Kenedi", birthday: "1998-07-06"}) {
    affected_rows
    returning {
      birthday
      id
      name
      publicId
    }
  }
}
  • Digunakan untuk membuat perubahan pada data (create, update, delete)
  • GraphQL menganggap ada side-effect dan perubahan pada dataset setelah operasi mutation
Arsitektur
Client
Databases / Microservice
Server
Client
Server

Konsep dan Arsitektur GraphQL

Ekosistem dan peralatan GraphQL

Layer Client:
  • Menangani permintaan data ke server (query) dan Menerima respon balik dari server

  • Memudahkan integrasi dengan View Layer Library seperti: React atau Vue

  • Meng-cache hasil query

  • Menangani kesalahan(error) dan validasi skema

  • Local state Management dan cache

  • Pagination

Ekosistem dan peralatan GraphQL

Popular GraphQL Client
Relay
Apollo Client

Ekosistem dan peralatan GraphQL

Peralatan GraphQL:

Implementsi GraphQL di client

Sebelum Praktek

Implementsi GraphQL di client

Course Relationships
  1. student to course - course event
  2. student - student to course
  • Many to many
  • One to many

  1. course - course event
  2. teacher - course event
  3. location - course event

Implementsi GraphQL di client

Apa yang akan dibuat:
  • Menampilkan jadwal kursus
  • Menampilkan peserta dalam bentuk table
  • Menampilkan detail kursus dengan nama, deskripsi, tanggal, waktu, lokasi, pengajar dan para peserta yang mengikuti kursus
  • Menambah daftar peserta

Implementsi GraphQL di client

Pasang Ekstensi Chrome Browser:

Implementsi GraphQL di client

npm install --save vue-apollo graphql apollo-client apollo-link-http apollo-cache-inmemory graphql-tag

Instalasi pustaka yang dibutuhkan

npm run serve
npm install

Implementsi GraphQL di client

Integrasi lib tadi di
main.js

import Vue from "vue";
import Vuesax from "vuesax";
import { Plugin } from "vue-fragment";
import "vuesax/dist/vuesax.css"; //Vuesax styles
import "material-icons/iconfont/material-icons.css";
import App from "./App.vue";
import router from "./router";

Vue
  .use(Vuesax)
  .use(Plugin);

Vue.config.productionTip = false;

new Vue({
  render: (h) => h(App),
  router,
}).$mount("#app");

Implementsi GraphQL di client

import Vue from "vue";
import Vuesax from "vuesax";
import { Plugin } from "vue-fragment";
import ApolloClient from "apollo-client";
import { HttpLink } from "apollo-link-http";
import { InMemoryCache } from "apollo-cache-inmemory";
import VueApollo from "vue-apollo";
import "vuesax/dist/vuesax.css"; //Vuesax styles
import "material-icons/iconfont/material-icons.css";
import App from "./App.vue";
import router from "./router";

Vue
  .use(Vuesax)
  .use(Plugin)
  .use(VueApollo);

Vue.config.productionTip = false;

// Create an http link:
const link = new HttpLink({
  uri: "https://exploregraphql.ikhsan.dev/v1beta1/relay",
  headers: { "x-hasura-admin-secret": "admin_graphql_ganteng" },
  fetch,
});
const client = new ApolloClient({
  link,
  cache: new InMemoryCache({
    addTypename: true,
  }),
});
const apolloProvider = new VueApollo({
  defaultClient: client,
});

new Vue({
  apolloProvider,
  render: (h) => h(App),
  router,
}).$mount("#app");
1. import library
2. Register VueApollo ke Vue middleware
3. hubungkan graphql server uri & headers, set default cache & apollo client
4. Register apollo client / provider ke vue instance
Integrasi lib tadi di main.js

>

_

Live coding...

Explore GraphQL

By ikhsanalatsary

Explore GraphQL

  • 162