Blog

๐ŸฅŠ Gato GraphQL vs WPGraphQL: pertarungannya!

Leonardo Losoviz
Oleh Leonardo Losoviz ยท

Pembaruan 01/05/2024: Lihat perbandingan Gato GraphQL vs WPGraphQL.

Hadirin sekaliannnnnnnnnnn, dan tuan-tuan.

Mengumumkan pertandingan yang akan datang

Selamat datang di MGM Grand Garden Arena untuk pertarungan abad ini! Malam ini, kita sedang membuat sejarah. Dua petarung muda akan berhadapan satu sama lain di atas ring, bersaing untuk hadiah yang telah mereka perjuangkan dengan keras:

Menjadi juara dunia "GraphQL di WordPress" ๐Ÿ†

Di sebelah kanan kami, kami memiliki juara saat ini. Meskipun baru berusia 4 tahun, ia sudah penuh pengalaman, setelah baru-baru ini mencapai versi 1.0 dan diterbitkan di direktori wp.org, dan sangat populer di kalangan penonton.

๐Ÿฅ Berikan ๐Ÿฅ sambutan ๐Ÿฅ kepada ๐Ÿฅ aaaaa ๐Ÿฅ ...... WPGraphQL!

Juara saat ini, WPGraphQL

Di sebelah kiri kami, kami memiliki penantang. Ia baru saja muncul di dunia selama 1 bulan, tetapi sangat energik dan ambisius, menampilkan kekuatannya sejak hari pertama. Dialah yang mencari pertemuan hari ini. Malam ini adalah kesempatannya, dan dunia sedang memperhatikan.

๐Ÿฅ Berikan ๐Ÿฅ sambutan ๐Ÿฅ kepada ๐Ÿฅ aaaaa ๐Ÿฅ ...... Gato GraphQL!

Penantang, Gato GraphQL

Malam ini, para kontestan kami akan bertemu muka untuk pertama kalinya, dalam pertarungan 12 ronde. Saat mereka mengambil posisi di tengah ring, menunggu bel pembuka, mereka saling mempelajari satu sama lain, mencoba menemukan titik lemah masing-masing. Namun, mereka hanya menampilkan kepercayaan diri.

2 petarung mulia saling mempelajari satu sama lain

Siapa yang akan menang? Apakah WPGraphQL akan mempertahankan keunggulannya, berdasarkan dukungan dari para pengikutnya? Atau apakah pendatang baru Gato GraphQL akan meyakinkan komunitas yang tidak curiga tentang kekuatan tinjunya, meninggalkan jejak kekaguman yang mengonversi penonton ke sisinya?

Malam ini, hadirin sekalian, kita akan mengetahuinya.

Pasang taruhan Anda. Dan nikmati pertandingannya!


๐Ÿคฃ๐Ÿคฃ๐Ÿคฃ๐Ÿคฃ๐Ÿคฃ๐Ÿคฃ๐Ÿคฃ๐Ÿคฃ๐Ÿคฃ๐Ÿคฃ๐Ÿคฃ๐Ÿคฃ๐Ÿคฃ๐Ÿคฃ๐Ÿคฃ๐Ÿคฃ๐Ÿคฃ๐Ÿคฃ


Saya baru-baru ini diminta untuk menjelaskan perbedaan antara plugin saya, Gato GraphQL, dan WPGraphQL.

Kedua plugin adalah server GraphQL untuk WordPress, sehingga mereka melayani tujuan yang sama. Namun, di balik permukaannya mereka memiliki karakteristik yang berbeda, yang dapat membuat satu lebih baik dari yang lain untuk memenuhi beberapa perilaku yang diperlukan.

Meskipun saya bias terhadap plugin saya sendiri, saya telah mencoba membuat perbandingan yang adil, berdasarkan topik yang saya anggap penting untuk GraphQL dan WordPress. (Jika pembaca menginginkan perbandingan tentang topik lain, saya akan dengan senang hati melakukannya.)

Perbandingan ini tidak lengkap. Misalnya, saya juga ingin melakukan beberapa benchmarking, mengukur kecepatan menyelesaikan query GraphQL yang sama dengan kedua server. (Jika pembaca menemukan proposal ini menarik, saya dapat melakukannya untuk artikel mendatang.)

Saya telah membagi perbandingan saya menjadi 4 area utama: Popularitas, Gaya kode dan standar, Hal-hal mendesak, dan Memperluas cakupan, dengan 3 item masing-masing, memberikan total 12 "ronde". Pada akhirnya, para juri memberikan putusannya, untuk menamai juaranya.

Klik di bawah untuk langsung menuju topik tertentu:

๐Ÿ”” Ding ๐Ÿ”” ding ๐Ÿ”” diiiiiing...

Bel pembuka telah berbunyi...

Pertandingan telah dimulai!


Popularitas

Setiap perangkat lunak (atau teknologi, dalam hal ini) harus digunakan oleh orang-orang, atau sebaliknya keunggulannya dibanding alternatif hanyalah sebuah anekdot.

Misalnya, meskipun ada alternatif yang memungkinkan mengetik lebih cepat, kita masih terutama menggunakan keyboard QWERTY.

Seberapa populer kedua plugin tersebut?

Ronde 1: Siapa yang menggunakannya, dan seberapa lengkap itu

WPGraphQL telah, hingga saat ini, menjadi sinonim dengan GraphQL di WordPress. Selama lebih dari 4 tahun pengembangannya (dimulai pada November 2016), ia mengumpulkan lebih dari 2.800 bintang di repo, komunitas lebih dari 4600 pengikut, dan hampir 100 kontributor untuk proyek ini.

Ia mencapai versi 1.0 dan diunggah ke direktori plugin di wp.org pada November 2020. Sejak saat itu, ia telah mengumpulkan lebih dari 8000 instalasi aktif. Saat ini merupakan satu-satunya solusi untuk mendapatkan konten WordPress ke Gatsby dan, baru-baru ini, beberapa proyek telah menambahkannya ke stack mereka, termasuk framework Headless WPEngine dan starter WordPress Next.js dari WebDevStudios.

Dengan kata lain, WPGraphQL populer.

Pengembangan Gato GraphQL dimulai dengan serius sekitar 1,5 tahun yang lalu (sebagai bagian dari proyek yang lebih besar), dan mencapai status "cukup baik" 6 bulan yang lalu, mendapat 150 bintang di repo sejak itu. Plugin ini saat ini berada di versi 0.7, dan masih beberapa bulan lagi sebelum mencapai 1.0 (misalnya, belum memiliki kategori di skema).

Bulan lalu saya meluncurkan situs ini gatographql.com, dan sejak itu saya telah mempromosikan plugin melalui blog (seperti artikel yang sedang Anda baca sekarang), dan juga menerbitkan artikel pengantar di CSS-Tricks. Upaya-upaya ini telah membawa beberapa ratus orang ke situs, dan lebih dari 100 pengunjung telah mengunduh plugin tersebut.

Dengan kata lain, Gato GraphQL secara perlahan tapi pasti semakin populer, dan masih dalam pengerjaan.

Pemenang ronde: WPGraphQL.

Ini pukulan telak! Tinju WPGraphQL mengenai Gato GraphQL

Ronde 2: Ketersediaan ekstensi

Ekstensi memungkinkan interaksi dengan plugin lain melalui Gato GraphQL.

WPGraphQL memiliki ekstensi untuk ACF, WooCommerce, Yoast dan beberapa lainnya.

Gato GraphQL belum memiliki ekstensi, dan saya tidak berharap akan ada banyak sebelum merilis versi 1.0.

Namun, Gato GraphQL sangat menekankan ekstensi dalam arsitekturnya, memungkinkan pengguna untuk mengelolanya (mengaktifkan, menonaktifkan, mengkonfigurasi, dan membaca dokumentasinya) dari satu tempat terpusat, halaman "Modules":

Halaman Modules di Gato GraphQL

Dengan kata lain, sementara WPGraphQL sudah memiliki ekstensi, Gato GraphQL sedang mempersiapkan landasan untuk mereka.

Pemenang ronde: WPGraphQL.

WPGraphQL memukul lagi!

Ronde 3: Target audiens

WPGraphQL menargetkan pengembang: jika Anda ingin mengekstrak data dari situs WordPress Anda, Anda perlu menyimpan query GraphQL Anda di suatu tempat dalam kode Anda (kemungkinan besar, dalam beberapa fungsi JavaScript). Kemudian, untuk dapat menggunakannya, Anda perlu cukup mahir dalam pemrograman.

Gato GraphQL, sebaliknya, mengikuti filosofi WordPress bahwa siapa saja harus bisa menggunakannya, termasuk non-teknisi. Untuk mencapai tujuan ini, ia memungkinkan pembuatan dan pengelolaan query GraphQL melalui editor WordPress, sehingga membuat data situs WordPress dapat diakses melalui API menjadi semudah membuat posting blog.

Selain itu, Gato GraphQL lebih menekankan penawaran klien untuk berinteraksi dengan layanan GraphQL secara visual. Sementara kedua plugin menyediakan klien GraphiQL, untuk mengeksekusi query, hanya Gato GraphQL yang juga menyediakan klien Voyager, untuk menjelajahi skema secara interaktif:

Memvisualisasikan skema GraphQL

Pemenang ronde: Gato GraphQL.

Gato GraphQL memberikan pukulan kiri yang bagus!


Gaya kode dan standar

Mari kita bicara tentang kode!

Jika Anda menggunakan GraphQL, kemungkinan besar Anda melakukan WordPress headless dan merender situs web menggunakan beberapa framework JavaScript, yang merupakan paradigma modern. Selain itu, WordPress mungkin CMS yang sudah tua, tetapi GraphQL adalah antarmuka modern untuk mengakses data dari situs. Oleh karena itu, saya dapat dengan aman mengasumsikan bahwa Anda adalah pengembang yang bijaksana, yang ingin menghasilkan kode yang elegan, dan tidak akan menerima penggunaan solusi yang tidak optimal.

Seberapa elegan kode (dari codebase mereka sendiri, dan yang diharapkan dari implementasi kustom kita) dari kedua plugin ini?

Ronde 4: Persyaratan PHP

Baik WPGraphQL maupun Gato GraphQL memerlukan PHP 7.1+.

Namun, ada perbedaan: Gato GraphQL sebenarnya dikodekan menggunakan PHP 7.4, dan kemudian di-transpile ke PHP 7.1 untuk produksi.

Oleh karena itu, mengkodekan Gato GraphQL jauh lebih menyenangkan: Anda dapat menggunakan fitur PHP yang lebih baru, termasuk tipe object, typed properties dan arrow functions. Dan setelah dukungan untuk PHP 8.0 ditambahkan (yang akan terjadi ketika versi baru Lando dirilis), Anda juga akan dapat menggunakan union types, ekspresi match, dan lainnya.

Pemenang ronde: Gato GraphQL.

Gato GraphQL meninggalkan bekasnya!

Ronde 5: Praktik pengkodean

Mari mulai dengan WPGraphQL. Menuju ke repo wp-graphql/wp-graphql, ada sesuatu yang menonjol bagi saya:

Folder vendor yang disimpan di repo

Diperbesar:

Isi folder vendor

Maaf, tetapi hanya ada satu cara saya bereaksi tentang ini:

Saya bisa memaafkan banyak hal dalam hidup, tapi bukan ini

Melakukan commit folder vendor Composer ke repo adalah praktik yang buruk, dan Composer secara eksplisit melarangnya.

Memperbaiki masalah ini tidak sulit (saya bahkan mendeskripsikan cara berdasarkan GitHub actions), jadi saya heran mengapa ini ada di sana.

Saya akan mengatakan bahwa, dalam ronde ini, WPGraphQL sedang memukul dirinya sendiri!

Aduh!

Mari lanjutkan. Mengembangkan untuk WPGraphQL memerlukan pengetahuan tentang koleksi hook yang sangat luas (action dan filter). Menuju ke Developer reference WPGraphQL, kita dapat menghargai luasnya hal ini.

Untuk mengambil screenshot daftar action, saya harus memperkecil browser ke 50%:

Action hooks untuk memperluas WPGraphQL

Untuk daftar filter, saya memperkecil ke 30% (yang terendah yang didukung Firefox), dan bahkan saat itu saya tidak bisa mendapatkan seluruh daftar:

Filter hooks untuk memperluas WPGraphQL


Mari beralih ke repo GatoGraphQL/GatoGraphQL, yang merupakan monorepo yang berisi Gato GraphQL (di antara proyek-proyek lainnya).

Berikut adalah beberapa karakteristik dari kode tersebut:

โœ… Mematuhi standar PSR-1, PSR-4 dan PSR-12.

โœ… Semua kode dibagi menjadi beberapa paket atomik, dan semuanya (lebih dari 100 untuk plugin, lebih dari 200 untuk keseluruhan proyek) dihosting di monorepo yang sama.

โœ… Menggunakan Composer untuk mengelola semua dependensi.

โœ… Menggunakan Symfony Dependency Injection untuk mengelola semua layanan dalam aplikasi. Untuk mendaftarkan type resolver, field resolver, atau directive resolver baru, kita hanya perlu mendaftarkan layanan baru di container.

โœ… Setiap class adalah sebuah layanan, dan Symfony Dependency Injection mengurus autowiring seluruh aplikasi bersama-sama.

โœ… Server GraphQL yang mendasarinya bersifat CMS-agnostic. Gato GraphQL mengimplementasikan kontrak untuk WordPress, dan menambahkan sedikit logika kustom (misalnya, untuk menyediakan klien).

Kode khusus WordPress hanya sekitar 10% dari keseluruhan kode. Mereplikasi 10% ini untuk framework atau CMS lain (Laravel/Drupal/dll) dapat memberikan implementasi server GraphQL untuk mereka juga.

โœ… Sebagai konsekuensi dari bersifat CMS-agnostic, mengkodekan sebuah resolver berarti mengkodekan logika bisnis generiknya, yang didukung oleh layanan yang dapat digunakan kembali. Kita tidak pernah berpikir dalam istilah kode WordPress, dan kita jarang perlu berurusan dengan utang teknisnya.

โœ… Demikian pula, skema GraphQL bukanlah replika 1:1 dari model data WordPress, melewati utang teknis yang terkumpul oleh WordPress di lapisan data, dan menyediakan antarmuka yang bersih.

โœ… Masalah N+1 GraphQL tidak dapat terjadi, berdasarkan desain arsitektur, dan tanpa menyusahkan pengembang sama sekali.

โœ… Server ini bukan hanya server GraphQL: sebenarnya ini adalah server API, di mana responsnya dapat dikeluarkan dalam format atau spesifikasi lain (misalnya: REST) dari satu sumber kebenaran tunggal. (Lebih lanjut tentang ini di ronde 11).

โœ… Tidak ada direktori vendor yang di-commit. Sebagai gantinya, kode sumber diubah menjadi kode distribusi (yaitu plugin akhir untuk dipasang di situs WordPress) melalui GitHub actions, dan di-deploy ke repo dist, di mana folder vendor tersebut ada.

โœ… Saat menghasilkan kode untuk distribusi, kode tersebut di-scope dengan PHP-Scoper, dan kode sumber, yang berisi kode PHP 7.4, di-transpile ke PHP 7.1.

โœ… Karena telah menyelesaikan masalah scoping, plugin dapat bergantung pada dependensi pihak ketiga mana pun. Saat ini, plugin menggunakan DependencyInjection Symfony, Cache dan Dotenv, Guzzle (untuk berinteraksi dengan API eksternal), Pipeline dari League, dan beberapa lainnya.

Ini penting bukan hanya untuk saat ini, tetapi juga untuk masa depan: saya dapat memiliki kepastian bahwa saya dapat menggunakan dependensi apa pun dari repositori Packagist, sehingga saya tidak perlu menemukan ulang roda.

โœ… Field berlangganan ke tipe, membuat skema GraphQL mudah diperluas.

Pemenang ronde: Gato GraphQL (dengan selisih yang besar, berani saya katakan, jika Anda tidak keberatan).

Setelah ronde yang berat, WPGraphQL butuh sedikit istirahat

Ronde 6: Memperluas skema

Mari tambahkan sebuah field ke skema GraphQL.

Kita mengikuti tutorial untuk WPGraphQL. Kode yang disarankan adalah yang di bawah ini. Ini mendeklarasikan sebuah action hook untuk mengeksekusi sebuah fungsi yang mendeklarasikan sebuah array. Baik deskripsi field maupun resolusinya disediakan di dalam array:

add_action( 'graphql_register_types', function() {
 
	register_graphql_field( 'RootQuery', 'myNewField', [
		'type' => 'String',
		'args' => [
			'myArg' => [
				'type' => 'String',
        'description' => __( 'Description for how the argument will impact the field resolver', 'your-textdomain' ),
			],
		],
		'resolve' => function( $source, $args, $context, $info ) {
			if ( isset( $args['myArg'] ) ) {
				return 'The value of myArg is: ' . $args['myArg'];
			}
			return 'test';
		},
	]);
 
});

Contoh ini sesederhana mungkin: resolver pada dasarnya tidak melakukan apa-apa. Namun, saya sudah kesulitan melihat kode dan langsung memahami apa yang dilakukannya. Tidak, saya tidak sedang mencemooh: semua warna dari kode itu di editor saya bersaing untuk mendapatkan perhatian saya. Selain itu, tidak ada pemisahan perhatian, dan kode tersebut tampaknya tidak terlalu dapat digunakan kembali.

Oleh karena itu, terserah pengembang (yaitu Anda) untuk membuat kode mudah dibaca, dapat digunakan kembali, bebas bug, dan banyak lagi, saat mengembangkan aplikasi; library itu sendiri tampaknya tidak banyak membantu dalam hal ini.

Saya menyebut gaya ini "ADD": Array-Driven Development. Saya tidak bisa mengatakan saya penggemar gaya ini.

(Untuk bersikap adil kepada WPGraphQL, ini adalah praktik pengkodean standar, dan juga merupakan yang digunakan oleh engine yang mendasarinya webonyx/graphql-php.)


Di Gato GraphQL, semua kode bersifat SOLID. Untuk mendaftarkan sebuah field di skema GraphQL, kita membuat sebuah class yang mengimplementasikan antarmuka FieldResolverInterface (sebenarnya, memperluas dari AbstractSchemaFieldResolver, yang memiliki banyak metode yang sudah diimplementasikan), dan kita mendaftarkannya di container.

Misalnya, kode ini menyediakan field username, email dan url ke tipe User:

class UserFieldResolver extends AbstractSchemaFieldResolver
{
  public static function getClassesToAttachTo(): array
  {
    return [
      UserTypeResolver::class,
    ];
  }
 
  public static function getFieldNamesToResolve(): array
  {
    return [
      'username',
      'email',
      'url',
    ];
  }
 
  public function getSchemaFieldDescription(TypeResolverInterface $typeResolver, string $fieldName): ?string
  {
    $descriptions = [
      'username' => $this->translationAPI->__("User's username handle", "users"),
      'email' => $this->translationAPI->__("User's email", "users"),
      'url' => $this->translationAPI->__("URL of the user's profile in the website", "users"),
    ];
    return $descriptions[$fieldName];
  }
 
  public function getSchemaFieldType(TypeResolverInterface $typeResolver, string $fieldName): ?string
  {
    $types = [
      'username' => SchemaDefinition::TYPE_STRING,
      'email' => SchemaDefinition::TYPE_EMAIL,
      'url' => SchemaDefinition::TYPE_URL,
    ];
    return $types[$fieldName];
  }
 
  public function resolveValue(TypeResolverInterface $typeResolver, object $user, string $fieldName, array $fieldArgs = [])
  {
    switch ($fieldName) {
      case 'username':
        return $this->usersAPI->getUserLogin($user);
 
      case 'email':
        return $this->usersAPI->getUserEmail($user);
 
      case 'url':
        return $this->usersAPI->getUserURL($user);
    }
 
    return null;
  }
}

Saya percaya bahwa solusi saya lebih elegan daripada solusi dari WPGraphQL. Namun, itu adalah masalah selera. Saya tahu bahwa banyak pengembang tidak keberatan dengan Array-Driven Development, dan bahkan lebih menyukainya karena, dalam satu blob kode yang padat, mereka dapat mengimplementasikan semua logikanya.

Pemenang ronde: seri.

Seri


Jeda

Betapa malamnya kita miliki, hadirin sekalian.

Waktu untuk menganalisis pertandingan sejauh ini

Kita telah mencapai pertengahan pertarungan, jadi ini adalah waktu yang tepat untuk jeda ke toilet, dan melakukan beberapa komentar tentang apa yang telah kita alami sejauh ini.

(Sementara itu, saya seharusnya menampilkan iklan dari sponsor saya. Sayangnya, saya belum memilikinya. Jika Anda ingin perusahaan Anda mendanai pengembangan Gato GraphQL, dan mendapatkan eksposur di media prime seperti acara ini, kirim saya pesan.)

Sponsori saya, untuk mendapatkan akses ke iklan prime untuk merek Anda

Betapa pertandingan yang kita miliki! WPGraphQL awalnya penuh api dan amarah! Ia memulai pertandingan dalam kondisi prima, memberikan pukulan yang sangat dahsyat kepada Gato GraphQL, yang hampir tidak bisa berdiri di atas dua kakinya. Pukulan demi pukulan demi pukulan. Saya tidak ingin berada di posisi Gato GraphQL.

Saya harus akui, saya pikir setelah 2 ronde pertama, pertandingan akan segera berakhir. Saya mengharapkan knock-down datang kapan saja. Melihat handuk melambaikan tanda menyerah. Tapi Gato GraphQL bertahan. Kita harus memberikan kredit kepadanya. Betapa tekad yang tak tergoyahkan, sungguh luar biasa!

Dan kemudian, transformasi terjadi. Di suatu tempat mulai dari ronde ke-3, Gato GraphQL tampaknya mendapatkan energi dari entah dari mana, dan mulai tidak hanya membela diri, tetapi juga melancarkan serangan balik, banyak di antaranya mendarat di wajah WPGraphQL. Saya melihat WPGraphQL gemetar dan goyah! Kita tidak pernah melihat hal seperti itu dari juara dunia kita saat ini. Betapa transformasi yang benar-benar luar biasa yang baru saja kita alami!

Dan kemudian, dengan kepercayaan diri lawannya yang terguncang, mulai dari ronde ke-4 Gato GraphQL mengambil inisiatif untuk melancarkan serangkaian pukulan mematikan. Itu mengejutkan! Untungnya yang menghadapinya adalah juara dunia kita, WPGraphQL, dan ia bisa menahan pukulan-pukulan itu, diangkat oleh sorak-sorai dan simpati dari penonton. Betapa pahlawan ia! Siapa pun yang lain pasti sudah menyerah di tempat, tetapi ia tidak, ia menanggung pukulan-pukulan itu sebagai juara yang ia miliki.

Tapi apakah juara, ia masih akan menjadi lebih lama? Belum ada yang di-knockout, belum ada yang melempar handuk. Pertarungan bisa sewaktu-waktu mengambil giliran yang menentukan. Kedua petarung tahu apa yang mereka inginkan, dan saya yakin mereka akan keluar lagi dengan segenap kekuatan mereka, dan segenap tekad mereka, untuk menyerang lawan mereka, untuk menang.

Betapa pertandingan yang kita miliki!

Dan sekarang, hadirin sekalian, kedua pejuang kembali ke ring.

Para kontestan kembali ke ring

Lanjutkan ke sisa pertarungan!


Hal-hal mendesak

Server GraphQL perlu memperhatikan banyak pertimbangan, hanya untuk memenuhi proposisi "ambil data yang Anda butuhkan, tidak lebih atau kurang".

Misalnya:

  • Seberapa amankah itu? Bagaimana kita memastikan kita tidak mengekspos data pribadi di endpoint publik?
  • Seberapa performantkah itu? Bagaimana kita bisa mengurangi beban pada server saat mengirimkan query yang sama berulang kali, sambil membuatnya secepat mungkin?
  • Seberapa sederhanakah itu? Seberapa baik terintegrasinya dengan WordPress, untuk memanfaatkan fitur-fitur yang disediakan oleh CMS?

Dan banyak pertanyaan lagi. Ini hanyalah contoh kecil yang telah saya pilih, dan yang akan saya tangani dalam 3 ronde berikutnya.

Ronde 7: Persisted queries

Persisted queries menggabungkan yang terbaik dari GraphQL dan REST: dibuat menggunakan GraphQL, sehingga tidak ada under/over fetching data, tetapi diterbitkan di server sebagai endpoint, dengan URL-nya sendiri.

Persisted queries memberikan manfaat-manfaat berikut:

โœ… Aman: alih-alih memberikan akses ke data apa pun melalui satu endpoint, kita dapat mendefinisikan terlebih dahulu data apa yang akan diekspos.

โœ… Cepat: karena diakses melalui URL-nya sendiri, dapat di-cache di setiap lapisan antara klien dan back-end (di server, CDN, browser) menggunakan standar HTTP caching.

WPGraphQL menawarkan dukungan untuk persisted queries melalui dua ekstensi berikut:

Selain itu, Jason Bahl (pencipta WPGraphQL) baru-baru ini mengumumkan bahwa dalam waktu dekat ia akan menambahkan dukungan untuk persisted queries di WPGraphQL.

Saya bertanya-tanya apa yang ada di pikirannya, karena sudah ada 2 ekstensi. Apa bedanya dengan yang itu? Mungkin ia ingin menjadikannya bagian dari core plugin, untuk memperkuat langkah-langkah keamanan plugin secara keseluruhan tanpa bergantung pada pihak ketiga?

Atau mungkin ia melihat implementasi dari Gato GraphQL, dan ingin memberikan pengalaman serupa, mengoperasikannya melalui editor visual alih-alih kode murni?

Yang membawa kita ke Gato GraphQL. Ia tidak hanya menawarkan persisted queries, tetapi telah berupaya menjadikannya bagian sentral dari penawaran:

โœ… Plugin memungkinkan menonaktifkan satu endpoint, dan pengguna didorong untuk mengekspos data hanya melalui persisted queries.

(Sebaliknya, WPGraphQL hanya menonaktifkan introspeksi secara default, bukan endpoint yang sebenarnya. Dengan kata lain, penyerang mungkin masih dapat mengakses data pribadi; mereka hanya dibuat tugasnya lebih sulit, karena mereka tidak akan tahu terlebih dahulu data pribadi apa yang ada.)

โœ… Ini terintegrasi secara mendalam dengan editor WordPress, sehingga membuat persisted query membutuhkan usaha yang sama seperti membuat posting blog, dan siapa saja dapat melakukannya, bukan hanya programmer.

โœ… Persisted queries tidak statis: mereka dapat menggunakan variabel GraphQL, yang nilainya dapat disediakan melalui parameter URL saat mengeksekusi endpoint.

Lihat pengalaman membuat dan mengeksekusi persisted query di plugin saya:

Pemenang ronde: Gato GraphQL.

Ronde 8: Caching

GraphQL memiliki titik lemah yang besar: tidak mudah di-cache. Alasannya adalah bergantung pada pengiriman operasi POST ke satu endpoint tunggal. Karena satu endpoint akan menghasilkan hasil yang berbeda, dan karena query dikirim di dalam body permintaan alih-alih parameter URL, maka kita tidak dapat memiliki satu endpoint yang di-cache.

Solusi standar yang ditawarkan oleh banyak server GraphQL adalah menggeser caching ke klien, dan mengandalkan ID objek sebagai pengidentifikasi entitas yang akan di-cache alih-alih URL endpoint. Library paling populer yang menyediakan fungsionalitas ini adalah klien Apollo.

Ada sebuah diskusi di repo WPGraphQL tentang semua opsi yang tersedia untuk caching WPGraphQL. Menariknya, sebagian besar dari mereka adalah alat eksternal (seperti klien Apollo, atau WordPress Object Cache), yang berarti menambahkan lapisan ekstra ke aplikasi, meningkatkan kompleksitasnya, dan juga mungkin membuatnya lebih lambat.

(Alasan-alasan ini pasti sebagian besar menjadi latar belakang keputusan untuk mengimplementasikan persisted queries secara native di WPGraphQL.)

Misalnya, klien Apollo berjalan, yah, di klien. Jika mengakses situs web dari ponsel kelas bawah, tanpa banyak daya, kode JavaScript tambahan itu akan berdampak pada kinerja aplikasi.

Demikian pula, pengembang yang bekerja dengan WordPress mungkin mahir dengan PHP, tetapi tidak begitu banyak dengan JavaScript. Sekarang, meng-cache API mereka berarti mereka perlu khawatir tentang lapisan JavaScript juga.

Gato GraphQL telah lebih cerdas tentang topik ini. Karena menyediakan persisted queries, artinya query dieksekusi di endpoint mereka sendiri, ia memungkinkan untuk meng-cache URL endpoint ini melalui HTTP caching.

Header HTTP caching memiliki nilai max-age yang dihitung secara otomatis dari semua nilai max-age untuk semua field dalam query, dan informasi ini dikonfigurasi menggunakan editor WordPress, pada basis per-field.

Sebagai konsekuensinya, API dapat di-cache di beberapa lapisan (di klien, CDN, dan server), dan ditangani secara native dalam plugin, tanpa perlu menambahkan lapisan lain.

Lihat video ini yang menampilkan bagaimana endpoint API sedang di-cache:

Pemenang ronde: Gato GraphQL.

Ronde 9: Integrasi dengan Gutenberg

Dulu Gutenberg akan menjadi masa depan WordPress. Tidak lagi: Gutenberg sekarang adalah masa kini WordPress (sehingga kita dapat menyebutnya sebagai editor WordPress), dan Full Site Editing telah menjadi masa depan baru.

Tidak perlu dikatakan, API kita perlu memiliki integrasi yang baik dengan editor WordPress. Ini berarti tidak hanya untuk mengambil dan memposting data untuk blok, tetapi juga untuk berpotensi mendukung fitur-fitur di editor WordPress itu sendiri.

Misalnya, karena subscription GraphQL dapat membuat server mendorong data ke klien secara real time, ini akan cocok untuk mendukung fitur pengeditan kolaboratif dan notifikasi.

WPGraphQL dapat melakukan query data blok melalui ekstensi WPGraphQL Gutenberg. Ekstensi ini membuat tipe baru untuk memetakan setiap blok, sehingga kita memiliki CoreParagraphBlock, CoreQuoteBlock, dll.

Gato GraphQL akan segera dapat melakukan query data blok (ini masih dalam pengerjaan). Namun, alih-alih membuat tipe baru per blok, ia akan memiliki tipe Block tunggal untuk mewakili semua blok, dan kemudian kita dapat mengekstrak metadata spesifik untuk beberapa blok berdasarkan namanya.

Misalnya, lihat bagaimana Anda dapat menerjemahkan konten di dalam blok paragraf (menggunakan direktif @strTranslate, yang terhubung ke Google Translate API):

query TranslateStringsInBlocks {
  post(by: { id: 1657 }) {
    title
    paragraphBlocks: blockDataItems(
      filterBy: { include: "core/paragraph" }
    )
    translatedParagraphBlocks: blockDataItems(
      filterBy: { include: "core/paragraph" }
    )
      @underJSONObjectProperty(by: { path: "attributes.content" })
        @underEachArrayItem
          @strTranslate(from: "en", to: "fr")
  }
}

Pemenang ronde: seri.


Memperluas cakupan

"Saya punya sebuah mimpi."

Blok-blok Gutenberg telah dikonsepkan untuk menyediakan satu antarmuka tunggal untuk membuat konten di WordPress, sangat menyederhanakan pengembangan kode untuk CMS, dan pembelajaran yang diperlukan dari pengguna.

Meskipun diperkenalkan untuk membuat konten, blok-blok secara perlahan mengambil alih semua area lain dari CMS, termasuk widget, menu dan, segera hadir, tema melalui Full Site Editing. Dan di masa depan, mereka juga akan mendukung kemampuan multibahasa dan pengeditan kolaboratif (fitur-fitur yang mungkin tidak terpikirkan oleh kita saat berpikir tentang blok), dan siapa tahu apa lagi.

Kita bisa berpikir tentang GraphQL dalam istilah yang sama: sebagai satu antarmuka tunggal untuk berinteraksi dengan data. Itu berarti, tidak hanya mengambil dan memposting data, tetapi interaksi apa pun yang melibatkan data, termasuk pengeditan.

WordPress memiliki kesempatan unik untuk benar-benar menjadi OS dari web: sebuah sistem yang didukung oleh Gutenberg, yang memungkinkan pengguna memasukkan jenis konten apa pun (teks, gambar, video, audio, dll), memprosesnya melalui alat-alatnya sendiri atau beberapa layanan berbasis cloud, dan menerbitkannya ke tujuan akhirnya, baik itu situs WordPress atau di tempat lain.

Tetapi di balik mimpi yang kuat ini, harus ada API yang benar-benar kuat, untuk memenuhi persyaratan apa pun yang kita berikan padanya. Sebuah API yang bisa didasarkan pada GraphQL, tetapi yang dirancang untuk juga melampaui keterbatasannya.

Ronde 10: Dukungan untuk direktif kustom

Awal ronde 10

WPGraphQL tidak dilengkapi dengan satu pun direktif. Saya tidak mengatakan ia tidak mendukungnya (engine-nya webonyx/graphql-php mendukungnya), tetapi bahwa ia tidak menawarkan implementasi dari direktif kustom apa pun.

"Lalu apa?" mungkin Anda pikir. "Untuk apa kita perlu direktif? Jika seseorang perlu memodifikasi hasil query, mereka bisa melakukannya di klien mereka sendiri!"

Mengapa saya butuh direktif?

Ini adalah masalah pendapat, dan tidak ada yang benar atau salah. Tapi izinkan saya memberi tahu Anda sesuatu: direktif adalah fitur yang sangat berguna, yang membantu membedakan GraphQL dari REST. Jika Anda tidak menggunakannya, kemungkinan besar Anda tidak memaksimalkan API Anda.

Direktif tidak diatur oleh spec, sehingga server GraphQL dapat mengimplementasikannya sesuka mereka, membuatnya sekuat yang mereka butuhkan. Itulah mengapa banyak fungsionalitas baru dalam GraphQL pertama kali diperkenalkan melalui direktif, seperti @stream dan @defer.

Gato GraphQL memperlakukan direktif dengan penuh hormat. Mereka dieksekusi hanya sekali dengan data dari semua entitas, untuk semua field yang diterapkan padanya (yang menjelaskan mengapa direktif @strTranslate dapat mengambil hasil dari Google Translate API dengan sangat cepat), dan engine GraphQL itu sendiri didasarkan pada pipeline direktif.

Ahhhh, tetapi Anda takut membuat semua kekuatan ini tersedia untuk pengguna, bukan? Itu adalah kekhawatiran yang valid. Tetapi kemudian, Anda bisa saja menghapus akses ke satu endpoint, dan menyediakan akses ke data hanya melalui persisted queries, di mana Anda (admin situs) adalah satu-satunya orang yang memiliki akses ke direktif.

Jadi atau Anda diuntungkan, atau tidak ada yang terjadi.

Jika Anda menyukai direktif, bagus, Anda akan menyukai Gato GraphQL! โค๏ธ

Tetapi, di sisi lain, jika Anda tidak menyukainya, tidak ada yang terjadi.

Pemenang ronde: Gato GraphQL.

(Jika Anda percaya bahwa "kita tidak butuh direktif busuk", tolong jangan marah kepada saya... Saya hanya melakukan pekerjaan saya.)

Ronde 11: Dukungan untuk REST

"Ahhhhh? REST? REST apa? Bukankah kita sedang membicarakan GraphQL di sini? Mengapa Anda membicarakan REST? Mengapa Anda ingin mempersulit hidup saya?"

Lebih dari ini, saya tidak bisa lakukan untuk Anda

Ya, pada pandangan pertama topik ini tampaknya tidak pada tempatnya. Tetapi saya telah menambahkannya dalam perbandingan ini karena alasan yang sangat sederhana: Matt Mullenweg telah mengatakan bahwa ia memeriksa GraphQL untuk potensi dimasukkan ke dalam inti WordPress, dan satu hal yang akan dikhawatirkan oleh kontributor adalah harus memelihara dua codebase.

Yang membawa pada pertanyaan yang jelas: dapatkah server GraphQL juga menangani REST?

Jawabannya adalah "sebagian ya" untuk WPGraphQL, dan "sepenuhnya ya" untuk Gato GraphQL.

Mengenai WPGraphQL. Adalah mungkin untuk mendefinisikan sebuah endpoint REST yang, saat diselesaikan, hanya mengeksekusi sebuah query GraphQL yang berisi field-field yang diperlukan, baik sebagai panggilan internal ke engine GraphQL, atau sebagai operasi POST eksternal yang dieksekusi terhadap webserver yang sama.

Tetapi itu tidak cukup untuk memenuhi WP REST API, karena ia juga memiliki JSON schema, dan kita tidak bisa tanpanya.

Mengenai Gato GraphQL. Saya harus mengakui saya beruntung, karena pengerjaan pada engine yang mendasarinya (model komponen sisi server yang disebut PoP) dimulai sekitar tahun 2013, yaitu beberapa tahun sebelum saya mengetahui sesuatu yang disebut GraphQL, dan proyek ini berkembang dengan beberapa ide-idenya sendiri (yang saya dokumentasikan dalam artikel vintage saya ini).

Kemudian, ketika saya mulai mengkodekan server GraphQL CMS-agnostic (di mana Gato GraphQL berdiri) sekitar 1,5 tahun yang lalu, saya menggabungkan ide-ide yang dikembangkan untuk PoP, dengan fondasi yang ditetapkan oleh GraphQL, menciptakan sistem yang mendukung spec GraphQL secara keseluruhan, sambil dapat menambahkan serangkaian fitur yang berbeda padanya.

Dalam hal ini, skema yang digunakan PoP adalah API-agnostic, dan merupakan superset dari skema GraphQL. Skema PoP berada di /api/graphql/?query=fullSchema.

Kemudian, lapisan server GraphQL memformat skema PoP mengikuti spesifikasi GraphQL, yang menghasilkan skema GraphQL. Dan demikian pula, kita dapat menghasilkan JSON schema yang diperlukan oleh WP REST API.

Menghasilkan JSON schema ini belum dilakukan, tetapi layak dilakukan.

Sekarang, yang telah dilakukan sudah, adalah menghasilkan respons dari query dalam berbagai format. Misalnya, query GraphQL ini:

{
  posts {
    id
    title
    date
    author {
      name
    }
  }
}

Ini juga diselesaikan melalui endpoint REST ini: /posts/api/rest/?query=id|title|date|author.name.

Dan kita tidak perlu berhenti di sana. Apakah Anda perlu menghasilkan hasil menggunakan format yang berbeda, seperti XML? Tidak masalah: /api/?query=posts.id|title|date|author.name&datastructure=xml.

(Ini bisa membantu mengimplementasikan proposal untuk alat import/export baru untuk WordPress, berdasarkan sebuah skema. Ini juga membuat sedikit lebih jelas apa yang saya katakan sebelumnya: satu antarmuka tunggal dapat mendukung semua interaksi data, baik di dalam CMS, maupun dari CMS dengan API eksternal.)

Pemenang ronde: Gato GraphQL.

Ronde 12: Dukungan untuk fitur-fitur baru

Apakah spec GraphQL sudah final? Jawabannya adalah tidak: spec terus berkembang. Saat ini, ada 100 issue terbuka, banyak di antaranya berisi proposal yang akan diformalkan suatu saat di masa depan.

Sekarang, di antara 100 issue tersebut, pasti akan ada fitur-fitur baru yang dapat kita manfaatkan hari ini, bukan? Jika demikian, mengapa harus menunggu?

Itulah persis cara berpikir saya.

Kita tidak bisa menunggu selamanya

"Tetapi jika sesuatu tidak ada dalam spec GraphQL, maka kita tidak boleh menambahkannya ke server GraphQL, atau pengguna akan bingung!"

Poin yang bagus. Namun, jika kita membuat fitur-fitur baru tersedia hanya sebagai opt-in, maka pengguna akan menjadi sadar tentang hal itu, dan tidak ada masalah atau kesalahpahaman yang akan terjadi.

Sekali lagi, itulah cara berpikir saya. Ini adalah masalah pendapat, jadi jika Anda lebih suka hanya menggunakan fitur-fitur yang setiap server GraphQL di luar sana juga menggunakannya, tidak apa-apa.

Saya percaya begitulah WPGraphQL beroperasi. Setidaknya, saya belum melihat satu pun fitur yang melampaui apa yang telah disetujui dalam spec.

Untuk Gato GraphQL, saya secara teratur memindai daftar issue dalam spec dan, jika saya menemukan fitur keren, yang dapat dipenuhi oleh server saya tanpa banyak usaha, maka saya mengimplementasikannya. (Memang, ini adalah salah satu hobi saya.)

Berikut adalah fitur-fitur "berwawasan ke depan" yang telah saya implementasikan hingga saat ini:

โœ… Eksekusi multiple query
โœ… Penamaan namespace skema
โœ… Nested mutations
โœ… Direktif yang dapat digabungkan
โœ… Umpan balik proaktif
โœ… Versioning berbasis field dan direktif

Dan saya sudah merencanakan untuk menambahkan:

โœณ๏ธ Subscriptions (ini sudah menjadi bagian dari spec)
โœณ๏ธ Direktif @stream dan @defer
โœณ๏ธ Flat chain syntax

Pemenang ronde: Gato GraphQL.


Putusan!

Hadirin sekalian.

Saatnya untuk putusan

Betapa malam yang tak terlupakan yang telah kita miliki! Betapa pertandingan yang baru saja kita saksikan! Dua petinju kelas berat memberikan yang terbaik untuk mimpi mereka.

Sebuah mimpi yang keduanya kejar, tetapi hanya satu yang bisa meraihnya.

Dan sekarang, kita akan tahu siapa orang itu. Sekarang, saatnya untuk kebenaran!

Siapa yang akan menjadi juara dunia "GraphQL di WordPress"?

Apakah itu akan menjadi yang sangat terkenal, dicintai-oleh-massa, ditampilkan-dalam-publikasi-besar juara saat ini, WPGraphQL?

Atau apakah itu akan menjadi yang tidak sopan, menginjak-jari-kaki-tanpa-meminta-maaf, datang-tanpa-diundang-ke-pesta penantang, Gato GraphQL?

Para kontestan menunggu putusan

Kita menunggu putusan dari hakim. Betapa tegangnya! Oh Santa Maria, buat hatiku tahan momen ini!

๐Ÿฅ Dan ๐Ÿฅ pemenangnya ๐Ÿฅ adaaaaaaaaaaaaaa ๐Ÿฅ ...

Ini seri!

2 petarung, 2 petinju kelas berat, mereka seri!

Para kontestan saling memeluk satu sama lain

Betapa momen yang indah! Kedua kontestan saling memeluk, menunjukkan bahwa kita semua adalah teman dalam komunitas WordPress, seperti keluarga besar yang kita adalah.

Jadi, apa justifikasi untuk seri tersebut? Hakim menjelaskan:

๐Ÿ‘‘ WPGraphQL adalah yang lebih populer, dan penggunaannya lebih tersebar luas.

๐Ÿ‘‘ Gato GraphQL memiliki arsitektur yang lebih baik, dan berpotensi lebih baik melayani WordPress dalam jangka panjang.

Hadirin sekalian, Anda telah mendapatkan putusan dari hakim!

Dan trofi kita memiliki dua sarung tinju: satu untuk setiap kontestan.

Trofi 'GraphQL di WordPress'

Tapi apa putusan Anda?

Apakah Anda akan terus menggunakan WPGraphQL secara tanpa syarat untuk kebutuhan headless Anda?

Atau apakah Anda akan memberikan Gato GraphQL kesempatan yang ia klaim, unduh plugin-nya, dan mencobanya?


Hadirin sekalian. Ini semua untuk malam ini.

Kami dengan tulus berharap Anda telah menikmati pertandingannya.

Dan semoga kita segera memiliki pertemuan baru antara dua juara kita.

Selamat malam.

Pembaruan 01/05/2024: Pelajari lebih lanjut dalam perbandingan Gato GraphQL vs WPGraphQL.


Berlangganan newsletter kami

Tetap update dengan semua pembaruan Gato GraphQL.