GraphQL-ning echimlari: eng yaxshi amaliyotlar

Graphql.org saytidan

Ushbu xabar PayPal-da GraphQL API-larini qurishda qilgan eng yaxshi tajribalar va kuzatuvlarning birinchi qismi. Kelgusi xabarlarda biz sxemalarni tuzish, xatolar bilan ishlash, ishlab chiqarishning ko'rinishi, mijozlar uchun integratsiyani optimallashtirish va jamoalar uchun vositalar bo'yicha fikrlarimiz bilan o'rtoqlashamiz.

Siz bizning oldingi "GraphQL: PayPalni tekshirish uchun muvaffaqiyat hikoyasi" PayPal-dan REST-dan GraphQL-ga sayohat haqida ko'rgan bo'lishi mumkin. Ushbu post vaqt o'tishi bilan tezkor, sinovdan o'tadigan va turg'un echimlarni yaratishda eng yaxshi tajribalarni batafsil bayon qiladi.

Nimani hal qilasiz?

Keling, xuddi shu boshlang'ichdan boshlaylik. Nimani hal qilasiz?

Resolver ta'rifi
Har bir turning har bir maydoni hal qiluvchi deb nomlangan funktsiya bilan ta'minlanadi.

Ruxsat beruvchi - bu sxemadagi tur yoki maydon uchun qiymatni aniqlaydigan funktsiya. Qo'llanmalar Strings, Raqamlar, Booleans va boshqalar kabi ob'ektlarni yoki skalyarni qaytarishi mumkin. Agar ob'ekt qaytarilsa, ijro keyingi bolalar maydonchasida davom etadi. Agar skalyar qaytarilsa (odatda barg tugunida), bajarish tugallanadi. Agar null qaytarilsa, ijro etish to'xtatiladi va davom etmaydi.

Resolverlar ham asenkron bo'lishi mumkin! Ular boshqa REST API, ma'lumotlar bazasi, kesh, doimiy va boshqalardan qiymatlarni hal qilishlari mumkin.

Keyinchalik, tezkor, sinovchan va egiluvchan echimlarni qanday qurish kerakligini ko'rsatuvchi bir qator misollarni ko'rib chiqamiz.

So'rovlarni bajarish

Ruxsat beruvchilarni yaxshiroq tushunish uchun so'rovlar qanday bajarilishini bilishingiz kerak.

Har bir GraphQL so'rovi uch bosqichdan o'tadi. So'rovlar tahlil qilinadi, tekshiriladi va bajariladi.

  1. Sintaksis - so'rov mavhum sintaksis daraxti (yoki AST) bilan taqqoslanadi. ASTs juda kuchli va ESLint, babel va boshqalar kabi vositalarning orqasida. Agar siz GraphQL AST ko'rinishini ko'rishni istasangiz, astexplorer.net saytini tekshiring va JavaScript-ni GraphQL-ga o'zgartiring. Siz chap tomonda so'rovni va o'ngda ASTni ko'rasiz.
  2. Validate - AST sxemaga qarshi tasdiqlangan. To'g'ri so'rov sintaksisini va maydonlar mavjudligini tekshiradi.
  3. Bajarish - ish vaqti daraxtning ildizidan boshlab AST bo'ylab yuradi, o'lchagichlarni chaqiradi, natijalarni to'playdi va JSON chiqaradi.

Ushbu misol uchun biz ushbu so'rovga murojaat qilamiz:

Keyinchalik murojaat qilish uchun so'rov

Ushbu so'rov tahlil qilinsa, u AST yoki daraxtga o'zgartiriladi.

So'rov daraxt sifatida berilgan

"Query root" turi daraxtga kirish nuqtasi bo'lib, bizning ikkita ildiz maydonimiz, foydalanuvchi va albomni o'z ichiga oladi. Foydalanuvchi va albom rezervlari parallel ravishda bajariladi (bu barcha ish vaqtlari uchun xosdir). Daraxt kengligi birinchi bo'lib bajariladi, ya'ni foydalanuvchi nomi va elektron pochtasi bajarilishidan oldin uni hal qilish kerak. Agar foydalanuvchi echuvchisi asenkron bo'lsa, uning tarmog'i hal qilinmaguncha kechiktiriladi. Barcha barg tugunlari, nomi, elektron pochta manzili, sarlavha hal qilingandan so'ng, bajarish tugallanadi.

Root Query maydonchalari foydalanuvchi va albom kabi parallel ravishda bajariladi, ammo hech qanday tartibda. Odatda, maydonlar so'rovda ko'rsatilgan tartibda bajariladi, ammo buni taxmin qilish xavfsiz emas. Maydonlar parallel ravishda bajarilganligi sababli, ular atom, idempotent va yon ta'sirsiz deb qabul qilinadi.

Qarorlarga yaqinroq

Keyingi bir nechta bo'limlarda biz JavaScript-ni ishlatamiz, ammo GraphQL serverlari deyarli har qanday tilda yozilishi mumkin.

To'rtta argument - ildiz, args, kontekst, ma'lumot

Qaysidir shaklda yoki boshqa shaklda, har bir tildagi har bir qaror chiqaruvchi quyidagi to'rtta dalilni oladi:

  • root - oldingi / ota-ona turidan olingan natija
  • args - dalalarga berilgan dalillar
  • kontekst - barcha hal qiluvchilarga taqdim etiladigan o'zgaruvchan ob'ekt
  • ma'lumot - so'rovga tegishli maydonga oid ma'lumotlar (kamdan kam ishlatiladi)

Ushbu to'rtta dalillar ma'lumotlarning rezervlar o'rtasida qanday o'tishini tushunish uchun asosiy hisoblanadi.

Standart o'lchagichlar

Davom etishdan oldin, shuni ta'kidlash kerakki, GraphQL serverida o'rnatilgan standart hal qiluvchi o'lchagichlar mavjud, shuning uchun har bir maydon uchun hal qiluvchi funktsiyasini ko'rsatishingiz shart emas. Maydon bilan bir xil bo'lgan mulkni topish uchun standart echuvchi ildizni qidiradi. Amalga oshirilish ehtimoli quyidagicha:

Standart hal qiluvchi dastur

Ruxsat beruvchilarda ma'lumotlar olinmoqda

Qayerdan ma'lumotlarni olishimiz kerak? Bizning imkoniyatlarimiz bilan qanday savdo qilish mumkin?

Keyingi bir nechta misollarda biz ushbu sxemaga qaytamiz:

Hodisa maydonida majburiy ID argumenti mavjud, Voqeani qaytaradi

Ruxsat beruvchilar o'rtasida ma'lumotlarni uzatish

kontekst bu barcha hal qiluvchilarga taqdim etiladigan o'zgaruvchan ob'ektdir. Har bir so'rov orasida yaratiladi va yo'q qilinadi. Bu Auth ma'lumotlarini, umumiy modellarni / API va ma'lumotlar bazalari uchun qabul qiluvchilarni va hokazolarni saqlash uchun juda yaxshi joy. PayPal-da biz Express-ga qurilgan katta Node.js do'konimiz, shuning uchun biz u erda Express 'req-ni saqlaymiz.

Kontekst haqida birinchi marta bilib olganingizda, kontekstni umumiy maqsadlar uchun kesh sifatida ishlatish birinchi fikr bo'lishi mumkin. Bu tavsiya etilmaydi, lekin bu erda amalga oshirish ko'rinishi quyidagicha bo'lishi mumkin.

Kontekstdan foydalangan holda hal qiluvchilar o'rtasida ma'lumotlarni uzatish. Bu tavsiya etilmaydi!

Sarlavha chaqirilganda biz voqea natijasini kontekstda saqlaymiz. PhotoUrl ishga tushirilganda, biz voqeani kontekstdan chiqarib tashlaymiz va undan foydalanamiz. Ushbu kod ishonchli emas. FotoUrl-dan oldin sarlavha bajarilishiga kafolat yo'q.

Hodisaning kontekstda mavjudligini tekshirish uchun ikkala hal qiluvchini tuzatdik. Agar shunday bo'lsa, undan foydalaning. Aks holda, biz uni olib, keyinroq saqlaymiz, ammo xatolar uchun hali ham katta sirt maydoni mavjud.

Buning o'rniga, echimlar ichidagi mutatsiya kontekstidan qochishimiz kerak. Bizning bilimlarimiz va tashvishlarimiz bir-biriga aralashmasin, shunda biz qarorlarimizni tushunamiz, tuzatamiz va sinovdan o'tkazamiz.

Ma'lumotni ota-onadan bolaga o'tkazish

Ildiz argumenti ma'lumotlarni ota-onadan tortib chiqaruvchilardan bolaga o'tkazuvchiga uzatishdir.

Masalan, siz Voqealar turini qurayotgan bo'lsangiz, unda Voqeaning barcha sohalari
bir xil ma'lumotga bog'liq bo'lsa, uni voqea maydonida bir marta olishni xohlashingiz mumkin,
emas, balki tadbirning har bir sohasida.

Yaxshi fikrga o'xshaydi, to'g'rimi? Bu hal qiluvchi vositalarni yaratishni boshlashning tezkor usuli, ammo siz ba'zi muammolarga duch kelishingiz mumkin. Sababini tushunaylik.

Quyidagi misollar uchun biz ikkita maydonga ega bo'lgan Voqealar turi bilan ishlaymiz.

Ikki maydonli voqea turi: sarlavha va fotoUrl

Voqealar uchun ko'p maydonlarini Event API-dan olish mumkin, shuning uchun biz uni eng yuqori darajadagi voqea hal qiluvchisiga olib kirishimiz va natijalarni sarlavhamizga va fotoUrl-ga yuklashimiz mumkin.

Yuqori darajadagi voqea hal qiluvchisi ma'lumotlarni oladi, sarlavha va photoUrl maydonini echuvchilarga natijalar beradi

Bundan ham yaxshisi, pastki ikkita o'lchagichni ko'rsatishga hojat yo'q.
Standart o'lchagichlardan foydalanishimiz mumkin, chunki getEvent () tomonidan qaytarilgan ob'ekt.
sarlavha va photoUrl xususiyatlariga ega.

id va sarlavha odatiy o'lchagich yordamida hal qilinadi

Nimasi yomon?

Ikki stsenariy bor, siz haddan tashqari oshirib yuborishingiz mumkin ...

1-stsenariy: Ko'p qatlamli ma'lumotlarni olish

Aytaylik, ba'zi talablar kiritilgan va siz tadbirga tashrif buyuruvchilarni ko'rsatishingiz kerak. Biz tadbirga qatnashuvchilar maydonini qo'shishdan boshlaymiz.

Qo'shimcha ishtirokchilar maydoni bilan tadbir turi

Ishtirokchilar tafsilotlarini olib kelganingizda, siz ikkita usulni tanlashingiz mumkin: bu ma'lumotni voqea tafsilotida yoki qatnashuvchilarni aniqlashda.

Birinchi variantni sinab ko'ramiz: uni voqea hal qiluvchisiga qo'shish.

voqea hal qiluvchisi ikkita API-ni chaqiradi, voqealar tafsilotlari va ishtirokchilar tafsilotlarini olib keladi

Agar mijoz faqat sarlavha va fotosurat so'rovini so'rasa, lekin qatnashmaganlar. Endi siz samarasiz bo'lib, sizning Attendees API-ga keraksiz so'rov yuborayapsiz.

Sizning aybingiz emas, biz shunday ishlaymiz. Biz naqshlarni aniqlaymiz va ularni nusxalashamiz.
Agar ishtirokchilar ma'lumotlarni yuklash voqea hal qiluvchida amalga oshirilganligini ko'rsalar, ular ehtimol shunday
U erda juda ko'p o'ylamasdan, qo'shimcha ma'lumotlar qo'shing.

Ishtirokchilarni hal qiluvchi ichida qatnashchilarni jalb qilish orqali bizda yana bir sinov usuli bor.

auditoriya qatnashuvchilarni qatnashuvchilarning ma'lumotlarini Attendees API-dan olishmoqda

Agar bizning mijozimiz sarlavha va fotoUrl-ni emas, faqat ishtirokchilarni so'rasa. Hodisalar API-ga keraksiz so'rov yuborib, biz hamon samarasizmiz.

№2 stsenariy: N ​​+ 1 muammo

Ma'lumotlar maydon darajasida yig'ilganligi sababli, biz haddan tashqari yuklanish xavfini tug'diramiz. Ortiqcha yuklash va N + 1 muammosi GraphQL dunyosidagi mashhur mavzu. Shopify-da N + 1 ni yaxshi tushuntiradigan ajoyib maqola mavjud.

Bu bizga qanday ta'sir qiladi?

Buni yaxshiroq ko'rsatish uchun biz barcha voqealarni qaytaradigan yangi voqealar maydonini qo'shamiz.

Hodisalar maydoni barcha voqealarni qaytaradi.Ularning nomi va ishtirokchilari bo'lgan barcha tadbirlarga so'rov

Agar mijoz barcha tadbirlarni va ularning ishtirokchilarini so'rasa, biz haddan tashqari haddan tashqari xafagarchilikni boshdan kechirishimiz mumkin, chunki ular bir nechta tadbirlarda qatnashishi mumkin. Xuddi shu ishtirokchi uchun takroriy so'rovlar yuborishimiz mumkin.

Ushbu muammo so'rovlar to'xtatilishi va tizimingizga keraksiz bosimni keltirib chiqarishi mumkin bo'lgan katta tashkilotda kuchaytirilgan.

Buni hal qilish uchun biz so'rovlarni to'kib tashlashimiz kerak.

JavaScript-da ba'zi mashhur variantlar - bu dataloader va Apollo ma'lumotlar manbalari.

Agar siz boshqa tilni bilsangiz, biror narsani tanlashingiz mumkin. Shuning uchun buni o'zingiz hal qilishdan oldin atrofga bir ko'z tashlang.

Uning negizida ushbu kutubxonalar ma'lumotlar kirish sathining yuqori qismida joylashgan bo'lib, chiquvchi so'rovlarni diskontlash yoki xotiradan foydalanib keshlaydi va o'chiradi. Agar siz asinx xotirasining qanday ko'rinishini bilmoqchi bo'lsangiz, Daniel Brainning ajoyib yozuvini tekshirib ko'ring!

Maydon darajasida ma'lumotlarni olish

Avvalroq, biz "ota-onadan bolaga" og'ir "og'irlikdagi" echimlar bilan haddan tashqari yuklash orqali kuyish osonligini ko'rdik.

Yaxshi alternativa bormi?

Keling, yana ota-onadan bolaga tanlovni aytaylik. Agar biz bolalar maydonlarimiz o'zlarining ma'lumotlarini olishlariga javobgar bo'lishini o'zgartirsak nima bo'ladi?

Maydonlar o'zlarining ma'lumotlarini olish uchun javobgardir.
Nima uchun bu yaxshiroq alternativa?

Ushbu kod haqida o'ylash oson. Siz elektron pochtani qaerga olib kelishini aniq bilasiz. Bu oson disk raskadrovka uchun qiladi.

Ushbu kodni sinab ko'rish mumkin. Haqiqatan ham sarlavha hal qiluvchini sinab ko'rmoqchi bo'lganingizda voqea ravshanligini sinab ko'rishingiz shart emas.

Ba'zilariga getEvent nusxasi kod hidi kabi ko'rinishi mumkin. Ammo sodda, mulohaza qilish oson va sinab ko'riladigan kodga ega bo'lish biroz nusxa ko'chirishga arziydi.

Ammo, bu erda hali ham muammo bo'lishi mumkin. Agar mijoz sarlavha va photoUrl haqida so'rasa, getEvent yordamida Event API-ga yana bitta qo'shimcha so'rov yuboramiz. Oldin N + 1 muammosida ko'rganimizdek, dataloader va Apollon ma'lumotlar manbalari kabi kutubxonalardan foydalanib, so'rovlarni doiraviy darajada o'chirishimiz kerak.

Agar biz ma'lumotlarni maydonlar darajasida olsak va so'rovlarni o'chirib qo'ysak, bizda disk raskadrovka qilish va sinash osonroq bo'lgan kod mavjud va biz bu haqda o'ylamasdan ma'lumotlarni optimallashtirishimiz mumkin.

Eng yaxshi amaliyotlar

  • Ota-onadan bolaga ma'lumotni olish va uzatish juda kam ishlatilishi kerak.
  • Pastki oqimdagi so'rovlarni bekor qilish uchun dataloader kabi kutubxonalardan foydalaning.
  • Ma'lumotlar manbalariga qanday bosim o'tkazayotganingizdan xabardor bo'ling.
  • "Kontekst" ni o'chirmang. Murakkab, kamroq buggy kodni ta'minlaydi.
  • O'qiladigan, saqlanadigan va sinovdan o'tkaziladigan o'lchamlarni yozing. Juda aqlli emas.
  • Qaroringizni iloji boricha ingichka qilib qo'ying. Qayta ishlatiladigan asinx funktsiyalarini olish uchun ma'lumotlarni olish mantig'ini chiqarib oling.

Yangiliklarni kuzatib boring, xabardor bo'lib boring; Biz bilan qoling!

Fikrlar? Biz sizning guruhingizning eng yaxshi amaliyotlari va puxta o'ylab ishlov beruvchilar bilan tanishishini eshitishni xohlaymiz. Ushbu mavzu tez-tez muhokama qilinmaydigan, ammo uzoq vaqt davomida ishlaydigan GraphQL API-larini yaratish uchun muhimdir.

Kelgusi xabarlarda biz sxemalarni tuzish, xatolar bilan ishlash, ishlab chiqarishning ko'rinishi, mijozlar uchun integratsiyani optimallashtirish va jamoalar uchun vositalar bo'yicha fikrlarimiz bilan o'rtoqlashamiz.

Biz yollaymiz! Agar siz GrafQL yoki PayPal-da reaksiya, DM-ni Twitterda @mark_stuart-da ishlashni xohlasangiz!