مقدمة كاملة إلى Apollo ، مجموعة أدوات GraphQL

Apollo عبارة عن مجموعة من الأدوات لإنشاء خادم GraphQL ، واستهلاك واجهة برمجة تطبيقات GraphQL. دعنا نستكشف Apollo بالتفصيل ، كل من Apollo Client و Apollo Server.

The Apollo Logo

مقدمة لأبولو

في السنوات القليلة الماضيةGraphQLاكتسب شعبية كبيرة كنهج بديل لبناء واجهة برمجة تطبيقات على REST.

تعد GraphQL طريقة رائعة للسماح للعميل بتحديد البيانات التي يريد نقلها عبر الشبكة ، بدلاً من جعل الخادم يرسل مجموعة ثابتة من البيانات.

أيضًا ، يسمح لك بتحديد الموارد المتداخلة ، مما يقلل كثيرًا من عمليات الرجوع والخلف المطلوبة أحيانًا عند التعامل مع واجهات برمجة تطبيقات REST.

Apollo هو فريق ومجتمع يبني على رأس GraphQL ، ويوفر أدوات مختلفة تساعدك في بناء مشاريعك.

الأدوات التي يوفرها Apollo هي بشكل أساسي 3:عميلوالخادمومحرك.

عميل أبولوتساعدك على استخدام واجهة برمجة تطبيقات GraphQL ، مع دعم لتقنيات الويب الأمامية الأكثر شيوعًا بما في ذلك React ،Vueو Angular و Ember و Meteor والمزيد ، وتطوير محلي على iOS و Android.

خادم أبولوهو جزء الخادم من GraphQL ، والذي يتفاعل مع الواجهة الخلفية ويرسل ردودًا إلى طلبات العميل.

محرك أبولوهي بنية تحتية مستضافة (SAAS) تعمل كوسيط بين العميل والخادم الخاص بك ، حيث توفر التخزين المؤقت ، وتقارير الأداء ، وقياس الحمل ، وتتبع الأخطاء ، وإحصائيات استخدام حقل المخطط ، والإحصائيات التاريخية والعديد من الأشياء الجيدة. إنه مجاني حاليًا حتى مليون طلب شهريًا ، وهو الجزء الوحيد من Apollo الذي ليس مفتوح المصدر ومجانيًا ، ويوفر التمويل للجزء مفتوح المصدر من المشروع.

تجدر الإشارة إلى أن هذه الأدوات الثلاثة ليست مرتبطة معًا بأي شكل من الأشكال ، ويمكنك استخدام Apollo Client فقط للتفاعل مع واجهة برمجة تطبيقات تابعة لجهة خارجية ، أو خدمة واجهة برمجة تطبيقات باستخدام خادم Apollo دون وجود عميل على الإطلاق ، على سبيل المثال.

كل شئمتوافق مع مواصفات GraphQL القياسية، لذلك لا توجد تقنية مملوكة أو غير متوافقة في Apollo.

ولكن من المريح جدًا أن يكون لديك كل هذه الأدوات معًا تحت سقف واحد ، مجموعة كاملة لجميع احتياجاتك المتعلقة بـ GraphQL.

يسعى أبولو جاهدًا ليكون سهل الاستخدام ويسهل المساهمة فيه.

يركز Apollo علىإبقاء الأمور بسيطة. هذا شيء أساسي لنجاح التكنولوجيا التي تريد أن تصبح شائعة ، حيث قد تكون بعض التقنيات أو الأطر أو المكتبات مبالغة بالنسبة لـ 99٪ من الشركات الصغيرة أو المتوسطة الموجودة هناك ، وهي مناسبة تمامًا للشركات الكبيرة ذات الاحتياجات المعقدة للغاية.

عميل أبولو

عميل أبولوهو عميل JavaScript رائد لـ GraphQL. يعتمد على المجتمع ، وهو مصمم للسماح لك ببناء مكونات واجهة المستخدم التي تتفاعل مع بيانات GraphQL ، إما في عرض البيانات ، أو في إجراء الطفرات عند حدوث إجراءات معينة.

لست بحاجة إلى تغيير كل شيء في تطبيقك للاستفادة من عميل Apollo. يمكنك البدء بطبقة واحدة صغيرة وطلب واحد والتوسيع من هناك.

الأهم من ذلك كله ، تم تصميم Apollo Client ليكون بسيطًا وصغيرًا ومرنًا من الألف إلى الياء.

في هذا المنشور ، سأقوم بتفصيل عملية استخدام Apollo Client داخل تطبيق React.

سأستخدم ملفواجهة برمجة تطبيقات GitHub GraphQLكخادم.

ابدأ تطبيق React

أنا أستعملcreate-react-appلإعداد تطبيق React ، وهو ملائم جدًا ويضيف فقط العناصر الأساسية لما نحتاج إليه:

npx create-react-app myapp

npxهو أمر متوفر في الأحدثnpmالإصدارات. قم بتحديث npm إذا لم يكن لديك هذا الأمر.

وابدأ تشغيل خادم التطبيق المحلي باستخدام npm:

npm start

سيؤدي هذا إلى تشغيل تطبيقlocalhost:3000.

مفتوح الانsrc/index.js:

import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import registerServiceWorker from './registerServiceWorker'

ReactDOM.render(<App />, document.getElementById(‘root’)) registerServiceWorker()

وإزالة كل هذا المحتوى.

ابدأ مع Apollo Boost

يعد Apollo Boost أسهل طريقة لبدء استخدام عميل Apollo في مشروع جديد. سنقوم بتثبيت ذلك بالإضافة إلىreact-apolloوgraphql.

في وحدة التحكم ، قم بتشغيل

npm install apollo-boost react-apollo graphql

قم بإنشاء كائن ApolloClient

تبدأ باستيراد ApolloClient منapollo-clientفيindex.js:

import { ApolloClient } from 'apollo-client'

const client = new ApolloClient()

بشكل افتراضي ، يستخدم عميل Apollo ملف/graphqlنقطة النهاية على المضيف الحالي ، فلنستخدم ملفرابط أبولولتحديد تفاصيل الاتصال بخادم GraphQL عن طريق تعيين URI لنقطة نهاية GraphQL.

يتم تمثيل ارتباط Apollo بامتدادHttpLinkالشيء الذي نستورد منهapollo-link-http.

يوفر لنا Apollo Link طريقة لوصف كيف نريد الحصول على نتيجة عملية GraphQL ، وما نريد فعله بالاستجابة.

باختصار ، يمكنك إنشاء العديد من مثيلات Apollo Link التي تعمل جميعها بناءً على طلب GraphQL واحدة تلو الأخرى ، مما يوفر النتيجة النهائية التي تريدها. يمكن أن تمنحك بعض الروابط خيار إعادة محاولة طلب ما إذا لم ينجح ، والتجميع وغير ذلك الكثير.

سنضيف رابط Apollo إلى مثيل Apollo Client الخاص بنا لاستخدام GitHub GraphQL endpoint URIhttps://api.github.com/graphql

import { ApolloClient } from 'apollo-client'
import { createHttpLink } from 'apollo-link-http'

const client = new ApolloClient({ link: createHttpLink({ uri: https://api.github.com/graphql }) })

التخزين المؤقت

لم ننتهي بعد. قبل الحصول على مثال عملي يجب أن نقول أيضًاApolloClientالتياستراتيجية التخزين المؤقتليستخدم:InMemoryCacheهو الإعداد الافتراضي وهو أمر جيد أن تبدأ.

import { ApolloClient } from 'apollo-client'
import { createHttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'

const client = new ApolloClient({ link: createHttpLink({ uri: https://api.github.com/graphql }), cache: new InMemoryCache() })

يستخدمApolloProvider

نحتاج الآن إلى توصيل عميل Apollo بشجرة المكونات الخاصة بنا. نحن نفعل ذلك باستخدامApolloProvider، من خلال تغليف مكون التطبيق الخاص بنا في ملف React الرئيسي:

import React from 'react'
import ReactDOM from 'react-dom'
import { ApolloClient } from 'apollo-client'
import { createHttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloProvider } from 'react-apollo'

import App from ‘./App’

const client = new ApolloClient({ link: createHttpLink({ uri: https://api.github.com/graphql }), cache: new InMemoryCache() })

ReactDOM.render( <ApolloProvider client={client}> <App /> </ApolloProvider>, document.getElementById(‘root’) )

هذا يكفي لتقديم الافتراضيcreate-react-appالشاشة ، مع تهيئة عميل Apollo:

create-react-app running Apollo Client

الgqlعلامة القالب

نحن الآن جاهزون للقيام بشيء ما باستخدام Apollo Client ، وسنقوم بجلب بعض البيانات من GitHub API وتقديمها.

للقيام بذلك نحتاج إلى استيراد ملفgqlعلامة القالب في بدايةindex.js:

import gql from 'graphql-tag'

سيتم إنشاء أي استعلام GraphQL باستخدام علامة القالب هذه ، مثل هذا:

const query = gql`
  query {
    ...
  }
`

قم بتنفيذ طلب GraphQL

استيرادgqlكان آخر عنصر نحتاجه في مجموعة أدواتنا.

نحن الآن جاهزون للقيام بشيء ما باستخدام Apollo Client ، وسنقوم بجلب بعض البيانات من GitHub API وتقديمها.

الحصول على رمز وصول لواجهة برمجة التطبيقات

أول شيء يجب القيام به هوالحصول على رمز وصول شخصيمن جيثب.

يسهل GitHub الأمر من خلال توفير واجهة تحدد من خلالها أي إذن قد تحتاجه:

GitHub interface to create a new personal access token

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

ما زلت بحاجة إلى رمز بالرغم من ذلك.

الرمز الذي تحصل عليه هو ملفالرمز المميز لحامل OAuth 2.0.

يمكنك اختباره بسهولة عن طريق التشغيل من سطر الأوامر:

$ curl -H "Authorization: bearer ***_YOUR_TOKEN_HERE_***" -X POST -d " \
 { \
   \"query\": \"query { viewer { login }}\" \
 } \
" https://api.github.com/graphql

(يحل محل***_YOUR_TOKEN_HERE_***مع الرمز الفعلي)

والتي يجب أن تعطيك النتيجة

{"data":{"viewer":{"login":"***_YOUR_LOGIN_NAME_***"}}}

أو

{
  "message": "Bad credentials",
  "documentation_url": "https://developer.github.com/v4"
}

إذا حدث خطأ ما ، على سبيل المثال إذا نسيت إدخال الرمز المميز.

الآن نحن بحاجة لإرسالتفويضمع طلب GraphQL ، تمامًا كما فعلنا في ملفcurlطلب أعلاه.

كيف نفعل ذلك مع Apollo Client هو عن طريق إنشاء برنامج وسيط Apollo Link. ابدأ بالتثبيتapollo-link-context:

npm install apollo-link-context

تتيح لنا هذه الحزمة إضافة آلية مصادقة من خلال تحديد سياق طلباتنا.

يمكننا استخدامه في هذا الرمز من خلال الرجوع إلىsetContextتعمل بهذه الطريقة:

import { setContext } from 'apollo-link-context'

const authLink = setContext((_, { headers }) => { const token = ‘*YOUR_TOKEN

return { headers: { …headers, authorization: Bearer </span><span style="color:#e6db74">${</span><span style="color:#a6e22e">token</span><span style="color:#e6db74">}</span><span style="color:#e6db74"> } } })

وبمجرد أن نحصل على رابط Apollo الجديد هذا ، يمكننا ذلكمؤلف موسيقىمعHttpLinkلدينا بالفعل ، باستخدامconcat()الطريقة على الرابط:

const link = authLink.concat(httpLink)

هذا هو الكود الكامل لملفsrc/index.jsملف مع الكود لدينا الآن:

import React from 'react'
import ReactDOM from 'react-dom'
import { ApolloClient } from 'apollo-client'
import { createHttpLink } from 'apollo-link-http'
import { InMemoryCache } from 'apollo-cache-inmemory'
import { ApolloProvider } from 'react-apollo'
import { setContext } from 'apollo-link-context'
import gql from 'graphql-tag'

import App from ‘./App’

const httpLink = createHttpLink({ uri: https://api.github.com/graphql })

const authLink = setContext((_, { headers }) => { const token = ‘*YOUR_TOKEN

return { headers: { …headers, authorization: Bearer </span><span style="color:#e6db74">${</span><span style="color:#a6e22e">token</span><span style="color:#e6db74">}</span><span style="color:#e6db74"> } } })

const link = authLink.concat(httpLink)

const client = new ApolloClient({ link: link, cache: new InMemoryCache() })

ReactDOM.render( <ApolloProvider client={client}> <App /> </ApolloProvider>, document.getElementById(‘root’) )

تحذير ⚠️ ضع في اعتبارك أن هذا الرمز هو ملفمثالللأغراض التعليمية ويعرض رمز GitHub GraphQL API الخاص بك للعالم ليراه في الشفرة التي تواجه الواجهة الأمامية. يحتاج كود الإنتاج إلى الحفاظ على خصوصية هذا الرمز المميز في الخلفية.

يمكننا الآن تقديم طلب GraphQL الأول في أسفل هذا الملف ، ويسأل نموذج الاستعلام هذا عن أسماء وأصحاب المستودعات العشرة الأكثر شيوعًا ، مع أكثر من 50 ألف نجمة:

const POPULAR_REPOSITORIES_LIST = gql`
{
  search(query: "stars:>50000", type: REPOSITORY, first: 10) {
    repositoryCount
    edges {
      node {
        ... on Repository {
          name
          owner {
            login
          }
          stargazers {
            totalCount
          }
        }
      }
    }
  }
}
`

client.query({ query: POPULAR_REPOSITORIES_LIST }).then(console.log)

يؤدي تشغيل هذا الرمز بنجاح إلى إرجاع نتيجة استعلامنا في وحدة تحكم المتصفح:

console log of executed query

تقديم مجموعة نتيجة استعلام GraphQL في أحد المكونات

ما رأيناه حتى الآن رائع بالفعل. والأكثر روعة هو استخدام مجموعة نتائج الرسم البياني لعرض مكوناتك.

نترك Apollo Client العبء (أو الفرح) أو جلب البيانات والتعامل مع جميع العناصر منخفضة المستوى ، ويمكننا التركيز على إظهار البيانات ، باستخدامgraphqlمعزز المكونات التي تقدمهاreact-apollo.

أضف هذا في ملفApp.jsملف:

import React from 'react'
import { graphql } from 'react-apollo'
import { gql } from 'apollo-boost'

const POPULAR_REPOSITORIES_LIST = gql </span><span style="color:#e6db74">{ </span><span style="color:#e6db74"> search(query: "stars:&gt;50000", type: REPOSITORY, first: 10) { </span><span style="color:#e6db74"> repositoryCount </span><span style="color:#e6db74"> edges { </span><span style="color:#e6db74"> node { </span><span style="color:#e6db74"> ... on Repository { </span><span style="color:#e6db74"> name </span><span style="color:#e6db74"> owner { </span><span style="color:#e6db74"> login </span><span style="color:#e6db74"> } </span><span style="color:#e6db74"> stargazers { </span><span style="color:#e6db74"> totalCount </span><span style="color:#e6db74"> } </span><span style="color:#e6db74"> } </span><span style="color:#e6db74"> } </span><span style="color:#e6db74"> } </span><span style="color:#e6db74"> } </span><span style="color:#e6db74">} </span><span style="color:#e6db74">

const App = graphql(POPULAR_REPOSITORIES_LIST)(props => <ul> {props.data.loading ? ‘’ : props.data.search.edges.map((row, i) => <li key={row.node.owner.login + ‘-’ + row.node.name}> {row.node.owner.login} / {row.node.name}: {’ '} <strong> {row.node.stargazers.totalCount} </strong> </li> )} </ul> )

export default App

هذه نتيجة الاستعلام الذي أجريناه في المكون 😀

The result of our query rendered in the component


خادم أبولو

وظيفة خادم GraphQL هي قبول الطلبات الواردة على نقطة نهاية ، وتفسير الطلب والبحث عن أي بيانات ضرورية لتلبية احتياجات العميل.

هناك الكثير من تطبيقات خادم GraphQL المختلفة لكل لغة ممكنة.

Apollo Server هو تطبيق خادم GraphQL لجافا سكريبت ، ولا سيما لـNode.jsمنصة.

يدعم العديد من أطر عمل Node.js الشائعة ، بما في ذلك:

يمنحنا خادم Apollo 3 أشياء بشكل أساسي:

  • يعطينا طريقة لوصف بياناتنا بامتدادمخطط.
  • يوفر الإطار لمحللات، وهي وظائف نكتبها لجلب البيانات اللازمة لتلبية الطلب.
  • يسهل التعاملالمصادقةلواجهة برمجة التطبيقات لدينا.

للبدء ، قم بإنشاء مجلد باسمappserver، اذهب إليه وركضnpm init --yesلتهيئة أpackage.jsonملف.

ثم اركضnpm install apollo-server graphql.

ملاعب أبولو

إذا كنت تفضل ملعبًا عبر الإنترنت ، فهناك ملعبان رائعان لأبولو أوصي بهما.

الأول مستضاف علىخلل، والثاني يومكود ساندبوكس.

اذهب وقم بإعادة مزج / شوكة تلك المشاريع المبدئية لإنشاء خادم Apollo الخاص بك.

خادم أبولو مرحبا العالم

يخترعindex.jsملف.

أولا تقوم بالاستيرادApolloServerوgqlمنapollo-server:

const { ApolloServer, gql } = require('apollo-server');

نقوم بإنشاء تعريف مخطط باستخدامgqlبطاقة شعار. تعريف المخطط هو سلسلة حرفية للقالب تحتوي على وصف الاستعلام الخاص بنا والأنواع المرتبطة بكل حقل:

const typeDefs = gql`
  type Query {
    hello: String
  }
`

أمحللهو كائن يقوم بتعيين الحقول في المخطط إلى وظائف المحلل ، وهو قادر على البحث عن البيانات للرد على استعلام.

يوجد هنا محلل بسيط يحتوي على وظيفة المحلل لـhelloالحقل الذي يُرجعHello world!خيط:

const resolvers = {
  Query: {
    hello: (root, args, context) => {
      return 'Hello world!'
    }
  }
}

بالنظر إلى هذين العنصرين ، تعريف المخطط والمحلل ، نقوم بتهيئة كائن ApolloServer جديد:

const server = new ApolloServer({ typeDefs, resolvers })

نسمي بعد ذلك التابع listen () على الكائن الخفيف ، ونستمع إلى الوعد بحلّه ، مما يشير إلى أن الخادم جاهز:

server.listen().then(({ url }) => {
  console.log(`🚀 Server ready at ${url}`)
})

إليك الكود الكامل لمثال Hello World البسيط:

const { ApolloServer, gql } = require('apollo-server');

// Construct a schema, using GraphQL schema language const typeDefs = gql </span><span style="color:#e6db74"> type Query { </span><span style="color:#e6db74"> hello: String </span><span style="color:#e6db74"> } </span><span style="color:#e6db74">

// Provide resolver functions for your schema fields const resolvers = { Query: { hello: (root, args, context) => { return ‘Hello world!’ } } }

const server = new ApolloServer({ typeDefs, resolvers })

server.listen().then(({ url }) => { console.log(🚀 Server ready at </span><span style="color:#e6db74">${</span><span style="color:#a6e22e">url</span><span style="color:#e6db74">}</span><span style="color:#e6db74">) })

الآن تشغيلnode index.jsومن نافذة وحدة تحكم أخرى ، قم بتشغيل:

$ curl \
  -X POST \
  -H "Content-Type: application/json" \
  --data '{ "query": "{ hello }" }' \
  http://localhost:4000/graphql

هذا يجب أن يعيد لك البيانات:

{
  "data": {
    "hello": "Hello world!"
  }
}

يمكنك الحصول على العميل الخاص بك ، والتعامل مع هذا باستخدام مثال ملف App.js البسيط ، والذي يمكنك تسجيله من مثال GitHub API أعلاه:

import React from 'react'
import { gql } from 'apollo-boost'
import { Query } from 'react-apollo'

const App = () => ( <Query query={gql</span><span style="color:#e6db74"> { </span><span style="color:#e6db74"> hello </span><span style="color:#e6db74"> } </span><span style="color:#e6db74"> } > {({ loading, error, data }) => { if (loading) return <p>Loading</p> if (error) return <p>Error :(</p>

  <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">data</span>.<span style="color:#a6e22e">hello</span>
}}

</Query> )

export default App

عليك تغييرhttpLinkuri فيindex.jsملف إلى:

const httpLink = createHttpLink({ uri: 'http://localhost:4000/graphql' })

المزيد من دروس الرسم البياني: