Arsitektur
ArsitekturDesain direktif

Desain direktif

Direktif memainkan peran penting: direktif memungkinkan implementasi fitur-fitur yang tidak didukung secara native oleh spesifikasi GraphQL maupun oleh server GraphQL itu sendiri. Direktif kemudian dapat membantu mengisi kekosongan dalam hal fungsionalitas, sehingga API dapat memenuhi kebutuhannya, baik yang sudah diketahui maupun yang belum.

Oleh karena itu, direktif merupakan elemen yang sangat penting dalam fondasi server GraphQL. Gato GraphQL mengandalkan desain arsitektur yang kokoh dan solid untuk direktif, yang memungkinkannya menjadi extensible sekaligus powerful.

Fungsionalitas tingkat rendah

Sebagai keputusan desain, engine bergantung langsung pada pipeline direktif untuk menyelesaikan query. Oleh karena itu, direktif diperlakukan sebagai komponen tingkat rendah, dengan akses ke objek tempat respons disimpan.

Hasilnya, setiap direktif kustom memiliki kemampuan untuk memodifikasi respons GraphQL.

Kasus penggunaan yang jelas untuk ini adalah direktif @remove, yang memungkinkan untuk menunjukkan dalam query apakah kita lebih memilih menghilangkan respons dari suatu field daripada menerima nilai null (ada sebuah issue dalam spesifikasi mengenai fitur ini).

Pemanggilan direktif yang efisien

Direktif menerima semua objek dan field yang terpengaruh secara bersamaan, dalam satu eksekusi tunggal.

Misalnya, pemanggilan API Google Translate harus dilakukan sesedikit mungkin. Dalam query ini, API dipanggil hanya sekali, yang memuat 10 potongan teks untuk diterjemahkan (2 field, title dan excerpt, untuk 5 posts):

query {
  posts(pagination:{ limit: 5 }) {
    title
    excerpt
    titleES: title @translate(from: "en", to: "es")
    excerptES: excerpt @translate(from: "en", to: "es")
  }
}

Dalam query ini terdapat 3 panggilan ke API, satu untuk setiap bahasa (Spanyol, Prancis, dan Jerman), masing-masing 10 string, semua panggilan dilakukan secara bersamaan:

query {
  posts(pagination:{ limit: 5 }) {
    title
    excerpt
    titleES: title @translate(from: "en", to: "es")
    excerptES: excerpt @translate(from: "en", to: "es")
    titleDE: title @translate(from: "en", to: "de")
    excerptDE: excerpt @translate(from: "en", to: "de")
    titleFR: title @translate(from: "en", to: "fr")
    excerptFR: excerpt @translate(from: "en", to: "fr")
  }
}

Tanda tangan fungsi

Ini adalah antarmuka direktif field. Perhatikan parameter yang diterima oleh fungsi resolveDirective:

public function resolveDirective(
  RelationalTypeResolverInterface $relationalTypeResolver,
  array $idFieldSet,
  FieldDataAccessProviderInterface $fieldDataAccessProvider,
  array $succeedingPipelineFieldDirectiveResolvers,
  array $idObjects,
  array $unionTypeOutputKeyIDs,
  array $previouslyResolvedIDFieldValues,
  array &$succeedingPipelineIDFieldSet,
  array &$succeedingPipelineFieldDataAccessProviders,
  array &$resolvedIDFieldValues,
  array &$messages,
  EngineIterationFeedbackStore $engineIterationFeedbackStore,
): void;

Parameter-parameter ini menunjukkan sifat tingkat rendah dari direktif:

  • $idFieldSet: daftar ID per field yang akan diproses oleh direktif
  • $succeedingPipelineIDFieldSet: daftar ID per field yang akan diproses oleh direktif pada tahap selanjutnya dalam pipeline
  • $resolvedIDFieldValues: objek respons

Parameter lainnya memungkinkan untuk: mengakses variabel query dan mendefinisikan variabel dinamis, meneruskan pesan dengan data kustom antar direktif, menampilkan error dan peringatan, mengidentifikasi dan menampilkan deprecation, serta menyimpan metrik.