สถาปัตยกรรม
สถาปัตยกรรมการออกแบบ Directive

การออกแบบ Directive

Directives มีบทบาทสำคัญ: ช่วยให้สามารถนำฟีเจอร์ที่ไม่ได้รับการรองรับโดยตรงใน GraphQL spec หรือตัว GraphQL server เองมาใช้งานได้ Directives จึงช่วยเติมเต็มช่องว่างด้านฟังก์ชันการทำงาน เพื่อให้ API สามารถตอบสนองความต้องการได้ ทั้งที่รู้อยู่แล้วและที่ยังไม่รู้

ด้วยเหตุนี้ directives จึงเป็นองค์ประกอบที่สำคัญอย่างยิ่งในรากฐานของ GraphQL server Gato GraphQL ใช้การออกแบบสถาปัตยกรรมที่มั่นคงและแข็งแกร่งสำหรับ directives ซึ่งทำให้สามารถขยายได้และมีประสิทธิภาพสูง

ฟังก์ชันระดับต่ำ

ในฐานะการตัดสินใจเชิงออกแบบ engine จะพึ่งพา directive pipeline โดยตรงในการแก้ไข query ด้วยเหตุนี้ directives จึงถูกจัดการเป็นคอมโพเนนต์ระดับต่ำ โดยมีสิทธิ์เข้าถึง object ที่เก็บ response ไว้

ผลลัพธ์คือ custom directive ใดๆ มีพลังในการแก้ไข GraphQL response ได้

ตัวอย่างที่ชัดเจนสำหรับสิ่งนี้คือ @remove directive ซึ่งช่วยให้สามารถระบุใน query ว่าต้องการละเว้น response จาก field แทนที่จะรับค่า null (มี issue ใน spec เกี่ยวกับฟีเจอร์นี้)

การเรียก Directive อย่างมีประสิทธิภาพ

Directives จะรับ object และ fields ที่ได้รับผลกระทบทั้งหมดพร้อมกันในการประมวลผลครั้งเดียว

ตัวอย่างเช่น การเรียก Google Translate API ควรทำให้น้อยครั้งที่สุดเท่าที่จะเป็นไปได้ ใน query นี้มีการเรียกเพียงครั้งเดียว โดยมีข้อความที่ต้องแปล 10 ชิ้น (2 fields คือ title และ excerpt สำหรับ 5 โพสต์):

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

ใน query นี้มีการเรียก API 3 ครั้ง โดยแต่ละภาษา (สเปน ฝรั่งเศส และเยอรมัน) 10 strings ต่อครั้ง โดยทุกการเรียกทำงานพร้อมกัน:

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")
  }
}

Function Signature

นี่คือ field directive interface โปรดสังเกตพารามิเตอร์ที่ฟังก์ชัน 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;

พารามิเตอร์เหล่านี้แสดงให้เห็นถึงลักษณะระดับต่ำของ directive:

  • $idFieldSet: รายการ IDs ต่อ field ที่จะถูกประมวลผลโดย directive
  • $succeedingPipelineIDFieldSet: รายการ IDs ต่อ field ที่จะถูกประมวลผลโดย directives ในขั้นตอนถัดไปของ pipeline
  • $resolvedIDFieldValues: response object

พารามิเตอร์อื่นๆ ช่วยให้สามารถ: เข้าถึง query variables และกำหนด dynamic variables, ส่งข้อความพร้อม custom data ระหว่าง directives, แจ้ง errors และ warnings, ระบุและแสดง deprecations, และบันทึก metrics