Blog

๐Ÿ›  Haruskah WordPress memiliki GraphQL API di core?

Leonardo Losoviz
Oleh Leonardo Losoviz ยท

Pembaruan 01/05/2024: Lihat perbandingan Gato GraphQL vs WP REST API.

WordPress 5.7 akan segera hadir. Seperti banyak rilis sebelumnya, WP REST API juga akan menghadirkan beberapa fitur baru.

Di antara fitur-fitur baru tersebut, satu hal menarik perhatian saya: "Image Editor Accepts a List of Modifiers".

Endpoint /wp/v2/media/<id>/edit yang diperkenalkan di WordPress 5.5 hadir dengan API terbatas yang menerima deklarasi rotasi dan crop di tingkat atas. Di 50124 API ini dibuat lebih kuat dan fleksibel dengan menerima array modifikasi dalam parameter permintaan modifiers yang baru.

import apiFetch from '@wordpress/api-fetch';
 
const data = {
  modifiers: [
    {
      type: 'crop',
      args: {
        left  : 0,
        top   : 0,
        width : 80,
        height: 80
      }
    },
    {
      type: 'rotate',
      args: {
        angle: 90
      }
    }
  ]
};
apiFetch( { data, method: 'POST', path: '/wp/v2/media/5/edit' } );

Pengembangan ini sudah berlangsung cukup lama.

Pertama, di WordPress 5.5, endpoint pengeditan gambar diperkenalkan.

Endpoint ini awalnya agak kaku, mengharuskan semua data terkait semua operasi yang akan diterapkan pada gambar dikirimkan sekaligus. Misalnya, untuk memutar gambar dan mengubah ukurannya, kita akan mengirimkan data ini:

{
  "x": 0,
  "y": 0,
  "width": 80,
  "height": 80,
  "rotate": 90
}

Kemudian, di WordPress 5.6, operasi batch diperkenalkan ke WP REST API.

Akhirnya, di WordPress 5.7 yang akan datang, operasi-operasi yang diterapkan pada gambar telah dipisahkan, sehingga kita memiliki operasi "crop" dan "rotate". Operasi-operasi ini dapat dijalankan secara mandiri, tetapi juga bersama-sama dalam satu permintaan melalui batching.

Seperti yang terlihat sebelumnya, mengirimkan data ke endpoint kini terlihat jauh lebih elegan:

{
  "modifiers": [
    {
      "type": "crop",
      "args": {
        "left"  : 0,
        "top"   : 0,
        "width" : 80,
        "height": 80
      }
    },
    {
      "type": "rotate",
      "args": {
        "angle": 90
      }
    }
  ]
}

Mengulang apa yang sudah ada?

WP REST API bukan satu-satunya API untuk WordPress. Ada (setidaknya) dua alternatif:

  • GraphQL, melalui WPGraphQL
  • GraphQL + persisted queries, melalui Gato GraphQL
    (โ˜๐Ÿฝ Ini saya, tuan rumah blog post ini โ˜๐Ÿฝ)

GraphQL adalah jenis API yang relatif baru, yang unggul dalam operasi batch. Jika menggunakan GraphQL, tidak perlu menghabiskan waktu dan energi untuk mengembangkan solusi khusus untuk operasi tersebut, seperti halnya dengan REST.

Memang, REST bisa dilihat sebagai "menyalin" fitur ini dari GraphQL.

REST menyalin GraphQL?

Mendukung operasi batch di WP REST API membutuhkan setidaknya 2, mungkin 3, siklus rilis untuk diselesaikan. Ini bukan jumlah waktu yang sedikit, dan memerlukan kontribusi dari beberapa orang.

Jika WordPress juga bisa memanfaatkan GraphQL, dan endpoint pengeditan gambar didasarkan pada GraphQL alih-alih REST, maka para kontributor tersebut bisa mengerjakan pengembangan lainnya.

Tidakkah WordPress akan lebih baik, dan berkembang jauh lebih cepat, jika bisa menggunakan kualitas terbaik dari setiap API, kapanpun memungkinkan?

Operasi batch dalam GraphQL

Saya akan menunjukkan tidak hanya satu, tetapi beberapa cara Gato GraphQL mendukung operasi batch.

Yang pertama adalah yang paling sederhana: menambahkan beberapa field ke root query. Misalnya, query ini melakukan login pengguna, lalu menambahkan komentar:

mutation LogUserInAndAddCommentToPost {
  loginUser(
    by: { credentials: { usernameOrEmail: "test", password: "pass" } }
  ) {
    id
    name
  }
  addCommentToCustomPost(
    input: {
      customPostID: 1459
      commentAs: { html: "Adding a comment: bla bla bla" }
    }
  ) {
    id
    content
    date
  }
}

(Btw, ini adalah klien GraphiQL. Berikut tutorial tentang cara menggunakannya.)

Sekarang, kedua operasi tersebut diterapkan pada objek yang berbeda, tetapi kita ingin menerapkan beberapa operasi pada objek yang sama.

Mari lakukan itu selanjutnya: query ini menambahkan dua komentar ke post yang sama.

mutation AddTwoCommentsToPost {
  firstComment: addCommentToCustomPost(
    input: {
      customPostID: 1459
      commentAs: { html: "This is my first response" }
    }
  ) {
    id
    content
    date
  }
  secondComment: addCommentToCustomPost(
    input: {
      customPostID: 1459
      commentAs: { html: "This is my second response" }
    }
  ) {
    id
    content
    date
  }
}

Kedua komentar ini ditambahkan ke post yang sudah ada. Tetapi apa yang akan terjadi jika post juga perlu dibuat terlebih dahulu?

Dalam kasus ini, query sederhana tidak akan berfungsi lagi, karena kita tidak mengetahui ID dari post yang belum dibuat, yang dibutuhkan sebagai argumen untuk operasi lainnya (perhatikan ? pada argumen field):

mutation CreatePostAndAddTwoCommentsToPost {
  createPost(input: { title: "Some post" }) {
    id  # <= I don't know what this value will be
  }
  addCommentToCustomPost(input: {
    customPostID: ?,
    commentAs: { html: "Blah blah blah" }
  }) {
    id
    content
    date
  }
}

Tapi jangan khawatir, Gato GraphQL siap membantu Anda. Plugin ini menyediakan tidak hanya satu, tetapi dua solusi!

GraphQL API peduli dengan Anda

Yang pertama adalah menggunakan fitur eksekusi multiple-query.

Dalam query ini, kita menjalankan operasi pertama, mengekspor hasilnya melalui direktif @export, lalu menyuntikkan nilai ini sebagai input ke query kedua:

mutation AddComment {
  addCommentToCustomPost(
    customPostID: 1459
    commentAs: { html: "Some insightful comment" }
  ) {
    id @export(as: "newCommentID")
    content
    date
  }
}
 
mutation AddResponseToComment @depends(on: "AddComment") {
  replyComment(
    parentCommentID: $newCommentID
    commentAs: { html: "Debunking your insightful comment" }
  ) {
    id
    date
    content
    parent {
      id
    }
  }
}

Lebih elegan lagi, kita bisa menggunakan nested mutations.

Dalam query ini, kita menjalankan operasi pertama, dan menyarangkan operasi kedua di dalamnya, sehingga akan diterapkan pada objek yang dibuat selama operasi pertama (dan kemudian diulang, menyarangkan operasi ke-3, dan seterusnya):

mutation AddCommentAndResponseAndResponse {
  addCommentToCustomPost(
    input: {
      customPostID: 1459
      commentAs: { html: "Some insightful comment" }
    }
  ) {
    id
    content
    date
    reply(input: { commentAs: { html: "Debunking your insightful comment" } }) {
      id
      date
      content
      parent {
        id
      }
      reply(input: { commentAs: { html: "No, it was right!" } }) {
        id
        date
        content
        parent {
          id
        }
      }
    }
  }
}

Sebagai bonus, operasi batch dapat diterapkan tidak hanya pada satu entitas, tetapi pada banyak entitas sekaligus, dalam satu permintaan yang sama.

Dalam query ini, komentar baru dan semua balasannya ditambahkan ke beberapa post:

mutation AddCommentAndResponseToManyPosts {
  posts(ids: [1657, 1153, 1499, 1459]) {
    id
    addComment(input: { commentAs: { html: "Some insightful comment" } }) {
      id
      content
      date
      reply(
        input: { commentAs: { html: "Debunking your insightful comment" } }
      ) {
        id
        date
        content
        parent {
          id
        }
      }
    }
  }
}

Dan plugin ini masih menyimpan satu trik lagi: dengan menggunakan fitur embeddable fields, kita bisa menyesuaikan konten yang dikirimkan ke setiap argumen field, menggunakan data dari objek itu sendiri!

Dalam query ini, komentar berisi informasi dari objek tempat mereka dibuat:

mutation AddCustomCommentAndResponseToManyPosts {
  posts(ids: [1657, 1153, 1499, 1459]) {
    id
    addComment(
      input: {
        commentAs: { html: "The post has ID {{ id }} and title {{ title }}" }
      }
    ) {
      id
      content
      date
      reply(
        input: {
          commentAs: {
            html: "The parent comment was posted on {{ dateStr(format: \"d/m/Y\") }}. Cool, right?"
          }
        }
      ) {
        id
        date
        content
        parent {
          id
        }
      }
    }
  }
}

Mendapatkan yang terbaik dari REST dan GraphQL kapanpun memungkinkan

Seiring Full Site Editing dikembangkan dan diperluas, WordPress akan semakin bergantung pada API-nya.

Mengenai fitur-fitur yang sudah ada, REST API sejauh ini berjalan sangat baik. Tidak perlu membangun ulang apa yang tidak rusak.

Namun, mengenai fitur-fitur baru yang belum dikembangkan, tidakkah WordPress diuntungkan dengan menggunakan REST atau GraphQL, tergantung mana yang lebih nyaman untuk fitur tertentu tersebut?

Jawabannya ada di tangan Anda...

Apa pendapat Anda?


Berlangganan newsletter kami

Tetap update dengan semua pembaruan Gato GraphQL.