GraphQL الآن ، دون مبالغة ، هذه هي آخر زقزقة في وضع تقنية المعلومات. وإذا كنت لا تعرف بعد نوع التقنية المستخدمة ، وكيفية استخدامها ، ولماذا قد تكون مفيدة لك ، فإن المقالة التي ننشرها اليوم مكتوبة من أجلك. سنقوم هنا باستعراض أساسيات GraphQL باستخدام مثال لتطبيق مخطط البيانات لواجهة برمجة التطبيقات لشركة الفشار. على وجه الخصوص ، دعنا نتحدث عن أنواع البيانات والاستعلامات والطفرات.

ما هو GraphQL؟
GraphQL هي لغة استعلام تستخدمها تطبيقات العميل للعمل مع البيانات. يرتبط GraphQL بمفهوم مثل "المخطط" - وهذا ما يسمح لك بتنظيم إنشاء وقراءة وتحديث وحذف البيانات في التطبيق الخاص بك (أي ، لدينا أربع وظائف أساسية تستخدم عند العمل مع مستودعات البيانات ، والتي يشار إليها عادةً بالاختصار CRUD - إنشاء ، قراءة ، تحديث ، حذف).
قيل أعلاه أن GraphQL يستخدم للعمل مع البيانات في "تطبيقك" وليس "في قاعدة البيانات الخاصة بك". الحقيقة هي أن GraphQL هو نظام مستقل عن مصادر البيانات ، أي أنه لا يهم أين يتم تنظيمه لتنظيم عمله.
إذا نظرت ، دون معرفة أي شيء عن GraphQL ، باسم هذه التقنية ، فقد يبدو أننا نواجه شيئًا معقدًا ومربكًا للغاية. اسم التكنولوجيا لديه كلمة "الرسم البياني". هل هذا يعني أنه من أجل إتقانها ، عليك أن تتعلم كيفية العمل مع قواعد بيانات الرسم البياني؟ وحقيقة أن الاسم يحتوي على "QL" (والتي يمكن أن تعني "لغة الاستعلام" ، أي "لغة الاستعلام") ، هل هذا يعني أن أولئك الذين يريدون استخدام GraphQL سيتعين عليهم تعلم لغة برمجة جديدة تمامًا؟
هذه المخاوف ليست مبررة تماما. من أجل طمأنتك - هذه هي الحقيقة القاسية حول هذه التقنية: إنها مجرد طلبات
GET
أو
POST
. بينما تقدم GraphQL ، بشكل عام ، بعض المفاهيم الجديدة المتعلقة بتنظيم البيانات والتفاعل معها ، تعتمد الآليات الداخلية لهذه التكنولوجيا على طلبات HTTP القديمة الجيدة.
إعادة التفكير في تقنية REST
المرونة هي ما يميز تقنية GraphQL عن تقنية REST المعروفة. عند استخدام REST ، إذا تم تنفيذ كل شيء بشكل صحيح ، فعادة ما يتم إنشاء نقاط النهاية مع مراعاة خصائص نوع بيانات مورد أو تطبيق معين.
على سبيل المثال ، عند تنفيذ طلب
GET
النهاية
/api/v1/flavors
من المتوقع أن يرسل ردًا يبدو كالتالي:
[ { "id": 1, "name": "The Lazy Person's Movie Theater", "description": "That elusive flavor that you begrudgingly carted yourself to the theater for, now in the comfort of your own home, you slob!" }, { "id": 2, "name": "What's Wrong With You Caramel", "description": "You're a crazy person that likes sweet popcorn. Congratulations." }, { "id": 3, "name": "Gnarly Chili Lime", "description": "The kind of popcorn you make when you need a good smack in the face."} ]
لا يوجد خطأ كارثي في هذه الإجابة ، ولكن دعونا نفكر في واجهة المستخدم ، أو بالأحرى ، كيف نعتزم استهلاك هذه البيانات.
إذا كنا نريد عرض قائمة بسيطة في الواجهة التي تحتوي فقط على أسماء أنواع الفشار المتاحة (وأي شيء آخر) ، فقد تبدو هذه القائمة مثل القائمة الموضحة أدناه.
قائمة أنواع الفشاريمكن أن نرى أننا هنا في وضع صعب. قد نقرر عدم استخدام حقل
description
، لكن هل سنجلس ونتظاهر أننا لم نرسل هذا الحقل إلى العميل؟ ماذا يمكن أن نفعل؟ وعندما يسألوننا بعد بضعة أشهر عن سبب بطء التطبيق بالنسبة للمستخدمين ، علينا فقط أن نسمح للرجل ولم يعد يجتمع مع إدارة الشركة التي صنعنا هذا التطبيق من أجلها.
في الواقع ، حقيقة أن الخادم يرسل بيانات غير ضرورية استجابة لطلب العميل ليست خطأنا بالكامل. REST هي عبارة عن آلية للحصول على البيانات يمكن مقارنتها بمطعم يسأل فيه النادل الزائر: "ماذا تريد؟" ، ولا يهتم بشكل خاص برغباته ، يقول له: "سأحضر لك ما لدينا" .
إذا وضعنا النكات جانباً ، فإن ذلك قد يؤدي إلى حدوث مشكلات في التطبيقات الحقيقية. على سبيل المثال ، يمكننا عرض معلومات إضافية متنوعة حول كل نوع من أنواع الفشار ، مثل معلومات الأسعار أو معلومات حول الشركة المصنعة أو المعلومات الغذائية ("Vegan Popcorn!"). في الوقت نفسه ، فإن نقاط النهاية REST غير المرنة تجعل من الصعب للغاية الحصول على بيانات محددة حول أنواع معينة من الفشار ، مما يؤدي إلى تحميل عالي بشكل غير معقول على الأنظمة وإلى حقيقة أن الحلول الناتجة أبعد ما تكون عن تلك التي قد يفخر بها المطورون.
كيف تحسن تقنية GraphQL ما هي تقنية REST المستخدمة في
قد يبدو التحليل السطحي للحالة الموصوفة أعلاه أننا مجرد مشكلة بسيطة. "ما الخطأ في إرسال البيانات غير الضرورية للعميل؟" لفهم المدى الذي يمكن أن تكون عليه "البيانات غير الضرورية" مشكلة كبيرة ، تذكر أن GraphQL تم تطويره بواسطة Facebook. هذه الشركة لديها لخدمة ملايين الطلبات في الثانية الواحدة.
ماذا يعني هذا؟ وحقيقة أنه مع مثل هذه المجلدات كل شيء يذكر.
GraphQL ، إذا واصلنا التشبيه مع مطعم ، فبدلاً من "نقل" الزائر "ما" ، يجلب بالضبط ما يأمر الزائر.
يمكننا الحصول على استجابة من GraphQL التي تركز على السياق الذي يتم فيه استخدام البيانات. في هذه الحالة ، لا نحتاج إلى إضافة نقاط وصول "لمرة واحدة" إلى النظام ، أو تنفيذ العديد من الطلبات أو كتابة هياكل شرطية متعددة الطوابق.
كيف يعمل GraphQL؟
كما قلنا من قبل ، تعتمد GraphQL على طلبات
GET
أو
POST
البسيطة لنقل البيانات إلى العميل واستلامها منها. إذا نظرنا إلى هذه الفكرة بمزيد من التفصيل ، اتضح أن هناك نوعين من الاستعلامات في GraphQL. يشتمل النوع الأول على طلبات لقراءة البيانات ، والتي في مصطلحات GraphQL تُسمى ببساطة الاستعلامات وتشير إلى الحرف R (القراءة ، القراءة) من اختصار CRUD. استعلامات النوع الثاني هي طلبات تعديل البيانات ، والتي تسمى الطفرات في GraphQL. إنها تتعلق بمربعات المحور C و U و D في اختصار CRUD ، أي أنها تستخدمها لإنشاء السجلات وإنشائها وتحديثها وحذفها.
يتم إرسال جميع هذه الطلبات والطفرات إلى عنوان URL لخادم GraphQL ، والذي قد يبدو ، على سبيل المثال ،
https://myapp.com/graphql
، في شكل طلبات
GET
أو
POST
. سنتحدث أكثر عن هذا أدناه.
استفسارات GraphQL
استعلامات GraphQL هي كيانات تمثل طلبًا للخادم لتلقي بيانات معينة. على سبيل المثال ، لدينا واجهة مستخدم معينة نريد تعبئتها بالبيانات. لهذه البيانات ، ننتقل إلى الخادم ، تنفيذ الطلب. عند استخدام واجهات برمجة تطبيقات REST التقليدية ، يأخذ طلبنا شكل طلب GET. عند العمل مع GraphQL ، يتم استخدام بناء جملة استعلام جديد:
{ flavors { name } }
هل هذا جسون؟ أو كائن جافا سكريبت؟ لا أحد ولا الآخر. كما قلنا من قبل ، باسم تقنية GraphQL ، تعني آخر حرفين ، QL ، "لغة الاستعلام" ، أي لغة الاستعلام. هذه ، حرفيًا ، لغة جديدة لكتابة طلبات البيانات. كل هذا يبدو وكأنه وصف لشيء معقد إلى حد ما ، ولكن في الواقع لا يوجد شيء معقد هنا. دعنا نحلل الاستعلام أعلاه:
{ // , . }
تبدأ جميع الطلبات بـ "طلب الجذر" ، ويطلق على الحقل ما تحتاج إلى الحصول عليه أثناء تنفيذ الطلب. من أجل إنقاذ نفسك من الارتباك ، من الأفضل استدعاء هذه الكيانات "حقول الاستعلام في المخطط". إذا بدا هذا الاسم غير مفهوم بالنسبة لك - انتظر قليلاً - أدناه سنتحدث أكثر عن المخطط. نحن هنا ، في الاستعلام الجذر ، نطلب حقل
flavors
.
{ flavors { // , flavor. } }
عند طلب حقل معين ، يجب أن نشير أيضًا إلى الحقول المتداخلة التي يجب تلقيها لكل كائن يأتي استجابة للطلب (حتى إذا كان من المتوقع أن يأتي كائن واحد فقط استجابة للطلب).
{ flavors { name } }
ماذا ستكون النتيجة؟ بعد أن نرسل مثل هذا الطلب إلى خادم GraphQL ، سوف نحصل على إجابة أنيقة جيدة التنظيم مثل ما يلي:
{ "data": { "flavors": [ { "name": "The Lazy Person's Movie Theater" }, { "name": "What's Wrong With You Caramel" }, { "name": "Gnarly Chili Lime" } ] } }
يرجى ملاحظة أنه لا يوجد شيء لا لزوم له. لجعلها أكثر وضوحًا ، إليك طلب آخر يتم تنفيذه للحصول على البيانات في صفحة أخرى من التطبيق:
{ flavors { id name description } }
استجابة لهذا الطلب ، حصلنا على ما يلي:
{ "data": { "flavors": [ { "id": 1, "name": "The Lazy Person's Movie Theater", description: "That elusive flavor that you begrudgingly carted yourself to the theater for, now in the comfort of your own home, you slob!" }, { "id": 2, "name": "What's Wrong With You Caramel", description: "You're a crazy person that likes sweet popcorn. Congratulations." }, { "id": 3, "name": "Gnarly Chili Lime", description: "A friend told me this would taste good. It didn't. It burned my kernels. I haven't had the heart to tell him." } ] } }
كما ترون ، GraphQL هي تقنية قوية للغاية. ننتقل إلى نفس نقطة النهاية ، وتتوافق إجابات الطلبات تمامًا مع ما هو مطلوب لملء الصفحة التي يتم تنفيذ هذه الطلبات منها.
إذا كنا بحاجة إلى الحصول على كائن
flavor
واحد فقط ، فيمكننا الاستفادة من حقيقة أن GraphQL يمكن أن يعمل مع الوسائط:
{ flavors(id: "1") { id name description } }
نحن هنا نضع بصرامة المعرف
id
للكائن في الكود ، المعلومات التي نحتاجها ، لكن في مثل هذه الحالات يمكننا استخدام المعرفات الديناميكية:
query getFlavor($id: ID) { flavors(id: $id) { id name description } }
هنا ، في السطر الأول ، نعطي الطلب اسمًا (يتم اختيار الاسم بشكل تعسفي ، ويمكن استبدال
getFlavor
بشيء مثل
pizza
، وسيظل الطلب قيد التشغيل) ونعلن عن المتغيرات التي يتوقعها الطلب. في هذه الحالة ، من المفترض أن يتم تمرير
id
(
id
)
ID
نوع العدد القياسي إلى الطلب (سنتحدث عن الأنواع أدناه).
بغض النظر عما إذا كان
id
استخدام
id
ثابت أو ديناميكي عند تنفيذ طلب ما ، إليك ما ستبدو عليه الاستجابة لطلب مماثل:
{ "data": { "flavors": [ { "id": 1, "name": "The Lazy Person's Movie Theater", description: "That elusive flavor that you begrudgingly carted yourself to the theater for, now in the comfort of your own home, you slob!" } ] } }
كما ترون ، يتم ترتيب كل شيء مريح للغاية. ربما تبدأ بالتفكير في استخدام GraphQL في مشروعك الخاص. وعلى الرغم من أن ما تحدثنا عنه بالفعل يبدو رائعًا ، إلا أن جمال GraphQL يظهر حقًا حيث يعمل مع الحقول المتداخلة. لنفترض أنه يوجد في مخططنا حقل آخر يسمى
nutrition
يحتوي على معلومات حول القيمة الغذائية لأنواع مختلفة من الفشار:
{ flavors { id name nutrition { calories fat sodium } } }
قد يبدو أنه في مستودع البيانات الخاص بنا ، سيحتوي كل كائن
flavor
على كائن
nutrition
متداخل. ولكن هذا ليس صحيحا تماما. باستخدام GraphQL ، يمكنك دمج المكالمات مع مصادر البيانات المستقلة ، ولكن ذات الصلة في استعلام واحد ، والذي يسمح لك بتلقي الإجابات التي توفر الراحة في العمل مع البيانات المضمنة دون الحاجة إلى إلغاء تجزئة قاعدة البيانات:
{ "data": { "flavors": [ { "id": 1, "name": "The Lazy Person's Movie Theater", "nutrition": { "calories": 500, "fat": 12, "sodium": 1000 } }, ... ] } }
هذا يمكن أن يزيد بشكل كبير من إنتاجية المبرمج وسرعة النظام.
حتى الآن ، تحدثنا عن طلبات القراءة. ماذا عن طلبات تحديث البيانات؟ هل استخدامها يعطينا نفس الراحة؟
طفرات GraphQL
أثناء تحميل استعلامات GraphQL البيانات ، تكون الطفرات مسؤولة عن إجراء تغييرات على البيانات. يمكن استخدام الطفرات في شكل آلية RPC (استدعاء الإجراء عن بُعد) الأساسية لحل المهام المختلفة ، مثل إرسال بيانات المستخدم إلى واجهة برمجة تطبيقات لجهة خارجية.
عند وصف الطفرات ، يتم استخدام بناء جملة يشبه الذي استخدمناه عند إنشاء الاستعلامات:
mutation updateFlavor($id: ID!, $name: String, $description: String) { updateFlavor(id: $id, name: $name, description: $description) { id name description } }
نعلن هنا طفرة
updateFlavor
، مع تحديد بعض المتغيرات -
id
name
description
. بالتصرف وفقًا لنفس المخطط المستخدم لوصف الاستعلامات ، نقوم "بإعداد" حقول متغيرة (طفرة الجذر) باستخدام الكلمة الأساسية
mutation
، متبوعةً باسم يصف الطفرة ، ومجموعة من المتغيرات اللازمة لتشكيل طلب تغيير البيانات المقابل.
تتضمن هذه المتغيرات ما نحاول تغييره ، أو ما هي الطفرة التي نرغب في إحداثها. يرجى أيضًا ملاحظة أنه بعد الطفرة ، يمكننا طلب إعادة بعض الحقول.
في هذه الحالة ، نحتاج إلى الحصول على حقول
id
name
description
بعد تغيير السجل. يمكن أن يكون هذا مفيدًا عند تطوير شيء مثل الواجهات المتفائلة ، مما يلغي الحاجة إلى تلبية طلب لتلقي البيانات التي تم تغييرها بعد تغييرها.
تصميم مخطط وتوصيله بخادم GraphQL
حتى الآن ، تحدثنا عن كيفية عمل GraphQL على العميل ، وكيفية تنفيذ الاستعلامات. الآن دعونا نتحدث عن كيفية الاستجابة لهذه الطلبات.
خادم raphGraphQL
لتنفيذ استعلام GraphQL ، تحتاج إلى خادم GraphQL يمكنك إرسال هذا الاستعلام إليه. خادم GraphQL هو خادم HTTP عادي (إذا كنت تكتب في جافا سكريبت ، فيمكن أن يكون خادمًا تم إنشاؤه باستخدام Express أو Hapi) ، مرفق به مخطط GraphQL.
import express from 'express' import graphqlHTTP from 'express-graphql' import schema from './schema' const app = express() app.use('/graphql', graphqlHTTP({ schema: schema, graphiql: true })) app.listen(4000)
من خلال "الانضمام" إلى مخطط ما ، فإننا نعني آلية لتمرير الطلبات الواردة من العميل عبر المخطط وإرجاع الإجابات إليه. يشبه مرشح الهواء الذي يدخل الهواء من خلاله الغرفة.
ترتبط عملية "التصفية" بالطلبات أو الطفرات التي يرسلها العميل إلى الخادم. يتم حل كل من الاستعلامات والطفرات باستخدام الدالات المتعلقة بالحقول المحددة في استعلام الجذر أو في طفرة الجذر في المخطط.
ما سبق هو إطار عمل لخادم HTTP تم إنشاؤه باستخدام مكتبة Express JavaScript. باستخدام وظيفة
graphqlHTTP
من
express-graphql
من Facebook ، "نرفق" المخطط (من المفترض أنه موصوف في ملف منفصل)
express-graphql
الخادم على المنفذ 4000. وهذا يعني أن العملاء الذين يتحدثون عن الاستخدام المحلي لهذا الخادم ، سيكونون قادرين على إرسال الطلبات عبر العنوان
http://localhost:4000/graphql
.
types أنواع البيانات والمحللات
لضمان تشغيل خادم GraphQL ، يلزمك إعداد المخطط وإرفاقه به.
تذكر أننا تحدثنا عن الإعلان عن الحقول في استعلام الجذر أو في طفرة الجذر أعلاه.
import gql from 'graphql-tag' import mongodb from '/path/to/mongodb' // - . , `mongodb` MongoDB. const schema = { typeDefs: gql` type Nutrition { flavorId: ID calories: Int fat: Int sodium: Int } type Flavor { id: ID name: String description: String nutrition: Nutrition } type Query { flavors(id: ID): [Flavor] } type Mutation { updateFlavor(id: ID!, name: String, description: String): Flavor } `, resolvers: { Query: { flavors: (parent, args) => { // , args , { id: '1' } return mongodb.collection('flavors').find(args).toArray() }, }, Mutation: { updateFlavor: (parent, args) => { // , args { id: '1', name: 'Movie Theater Clone', description: 'Bring the movie theater taste home!' } // . mongodb.collection('flavors').update(args) // flavor . return mongodb.collection('flavors').findOne(args.id) }, }, Flavor: { nutrition: (parent) => { return mongodb.collection('nutrition').findOne({ flavorId: parent.id, }) } }, }, } export default schema
يتكون تعريف الحقول في مخطط GraphQL من جزأين - من تعريفات النوع (
typeDefs
)
typeDefs
. يحتوي
typeDefs
على تعريفات للبيانات المستخدمة في التطبيق. على سبيل المثال ، تحدثنا سابقًا عن طلب للحصول على قائمة كائنات
flavor
من الخادم. لتقديم طلب مماثل لخادمنا ، يلزمك تنفيذ الخطوات الثلاث التالية:
- أخبر المخطط كيف تبدو بيانات كائن
flavor
(في المثال أعلاه ، يبدو كإعلان من type Flavor
). - قم بتعريف الحقل في الحقل الجذر
type Query
(هذه هي خاصية flavors
الخاصة بقيمة type Query
). - قم بتعريف دالة أداة التعرف على الكائنات في
type Query
resolvers.Query
مكتوبة وفقًا للحقول المعلنة في مجال الجذر type Query
.
الآن دعنا ننتبه إلى
typeDefs
. هنا نقدم معلومات المخطط حول شكل بياناتنا. بمعنى آخر ، فإننا نخبر GraphQL عن الخصائص المختلفة التي قد تكون موجودة في كيانات من النوع المقابل.
type Flavor { id: ID name: String description: String nutrition: Nutrition }
يشير إعلان
type Flavor
إلى أن كائن
flavor
قد يحتوي على حقل
id
النوع ، وحقل
name
النوع
String
، وحقل
description
للنوع
String
وحقل
Nutrition
للنوع
Nutrition
.
في حالة
nutrition
نستخدم هنا اسم نوع مختلف معلن في
typeDefs
. هنا ، يصف بناء
type Nutrition
شكل البيانات الغذائية للفشار.
انتبه إلى حقيقة أننا هنا ، كما في بداية هذه المادة ، نتحدث عن "تطبيق" وليس عن "قاعدة بيانات". في المثال أعلاه ، من المفترض أن لدينا قاعدة بيانات ، لكن البيانات في التطبيق يمكن أن تأتي من أي مصدر. يمكن أن يكون واجهة برمجة تطبيقات لجهة خارجية أو ملف ثابت.
تمامًا كما فعلنا في إعلان
type Flavor
، فإننا نحدد هنا أسماء الحقول التي سيتم تضمينها في كائنات
nutrition
، باستخدام ما يسمى في GraphQL أنواع البيانات العددية ، باعتبارها أنواع بيانات لهذه الحقول (الخصائص). في وقت كتابة هذا التقرير ، كان GraphQL يدعم
5 أنواع من البيانات العددية المدمجة :
Int
: وقع عدد صحيح 32 بت.Float
: رقم Float
مزدوج الدقة مع علامة.String
: سلسلة من الأحرف المشفرة في UTF-8.Boolean
: منطقية true
أو false
.ID
: ID
فريد يستخدم غالبًا لتحميل الكائنات أو كمفتاح في ذاكرة التخزين المؤقت. ID
تسلسل لقيم ID
النوع بالطريقة نفسها التي يتم بها استخدام السلاسل ، ومع ذلك ، يتم التأكيد على الإشارة إلى أن نوع ID
له قيمة من خلال حقيقة أن هذه القيمة لا تهدف إلى إظهارها للناس ، ولكن للاستخدام في البرامج.
بالإضافة إلى هذه الأنواع العددية ، يمكننا أيضًا تعيين خصائص لأنواع نعرّفها بأنفسنا. هذا هو بالضبط ما قمنا به من خلال تعيين خاصية
nutrition
الموصوفة في
type Flavor
، نوع
Nutrition
build.
type Query { flavors(id: ID): [Flavor] }
في بناء
type Query
، الذي يصف نوع الجذر الخاص بالاستعلام ("استعلام الجذر" الذي تحدثنا عنه سابقًا) ، نعلن اسم الحقل الذي يمكن طلبه. بإعلان هذا الحقل ، نقوم بالإضافة إلى نوع البيانات التي نتوقع إرجاعها ، بتحديد الوسائط التي قد تأتي في الطلب.
في هذا المثال ، نتوقع استلامًا محتملًا للوسيطة
id
نوع العدد. استجابة لمثل هذا الطلب ، من المتوقع ظهور مجموعة من الكائنات التي يشبه الجهاز جهاز من نوع
Flavor
.
izer توصيل أداة التعرف على الاستعلام
,
type Query
field
, , -.
— , GraphQL, , «».
resolvers
,
Query
, ,
flavors
, .
flavors
,
type Query
.
typeDefs: gql`…`, resolvers: { Query: { flavors: (parent, args) => { // , args { id: '1' } return mongodb.collection('flavors').find(args).toArray() }, }, … },
- .
parent
— , ,
args
, .
context
, . «» ( — , ).
, , . GraphQL « » . , , .
GraphQL , , . JSON-, JSON-, ( GraphQL ).
-
flavors
MongoDB,
args
( )
.find()
, , .
▍
-, GraphQL, , , ,
nutrition
. , ,
Nutrition
, , , ,
flavor
. , / .
GraphQL ,
type Flavor
nutrition
type Nutrition
, . , ,
flavor
.
typeDefs: gql` type Nutrition { flavorId: ID calories: Int fat: Int sodium: Int } type Flavor { […] nutrition: Nutrition } type Query {…} type Mutation {…} `, resolvers: { Query: { flavors: (parent, args) => {…}, }, Mutation: {…}, Flavor: { nutrition: (parent) => { return mongodb.collection('nutrition').findOne({ flavorId: parent.id, }) } }, },
resolvers
, ,
Query
,
Mutation
Flavor
. ,
typeDefs
.
Flavors
, ,
nutrition
-. ,
Flavor
. , : « ,
nutrition
,
type Flavor
».
MongoDB, ,
parent
, -. ,
parent
, , ,
flavors
. ,
flavor
, :
{ flavors { id name nutrition { calories } } }
flavor
,
flavors
,
nutrition
,
parent
. , , , MongoDB,
parent.id
,
id
flavor
, .
parent.id
,
nutrition
flavorId
,
flavor
.
▍
, , . , .
type Mutation
, ,
updateFlavor
, , .
type Mutation { updateFlavor(id: ID!, name: String, description: String): Flavor }
: « ,
updateFlavor
id
ID
( ,
!
, GraphQL , ),
name
String
description
String
». , ,
Flavor
( — ,
id
,
name
,
description
, , ,
nutrition
).
{ typeDefs: gql`…`, resolvers: { Mutation: { updateFlavor: (parent, args) => { // , args { id: '1', name: 'Movie Theater Clone', description: 'Bring the movie theater taste home!' } // . mongodb.collection('flavors').update( { id: args.id }, { $set: { ...args, }, }, ) // flavor . return mongodb.collection('flavors').findOne(args.id) }, }, }, }
-
updateFlavor
, : , , — ,
flavor
.
, ,
flavor
. ?
, , . ,
flavor
, .
args
? , . , , , 100% , . , , , , , .
GraphQL?
, , , , , GraphQL-API.
, GraphQL , . , . , . , , , GraphQL REST . , , , GraphQL.
▍ ,
, HTTP-, , , , — . GraphQL , , , , ( ).
, , ( — ), GraphQL .
▍ , ,
, , « ». , , , . . GraphQL .
▍ ,
REST API, : , . , -, iOS Android, API . , , , , « » .
, , , HTTP, API (, , ).
▍ GraphQL — ? REST API GraphQL?
, . . , , GraphQL . GraphQL, . , , , . , , .
, GraphQL , , , . GraphQL , Apollo Relay, .
GraphQL — , , .
graphql
(
express-graphql
, ) — . , GraphQL - . , -, , , , .
النتائج
, GraphQL , . GraphQL , , , . , , , , GraphQL.
, : GraphQL . GraphQL . , GraphQL, , , , , , , .
— , GraphQL — , , . GraphQL , . , GraphQL — , , , . . , , , , , , GraphQL.
أعزائي القراء! GraphQL — , .
