كيفية إنشاء خادم GraphQL باستخدام Node.js و Express

برنامج تعليمي بسيط حول كيفية إنشاء خادم GraphQL مدعوم من Node.js و Express

ابدأ بإنشاء مشروع Node.js جديد ، إذا لم تكن قد أعددته بالفعل:

npm init --y

يقوم هذا الأمر بإنشاء ملفpackage.jsonالملف الذي نحتاج إلى العمل معهnpm.

قم بتثبيت حزم npmexpressوgraphqlوexpress-graphql:

npm install express graphql express-graphql

يخترعapp.jsملف ، ولنبدأ بتهيئة ملفالتعبيرالخادم:

const express = require('express')

const app = express()

app.listen(3000, () => { console.log(‘App listening on port 3000’) })

الآن نضيفexpress-graphql. هذا الالوسيطة، ونطبقه على مسار فقط ،/graphqlطريق:

const express = require('express')
const graphqlHTTP = require('express-graphql')

const app = express()

app.use(’/graphql’, graphqlHTTP())

app.listen(3000, () => { console.log(‘App listening on port 3000’) })

يجب أن نمرر كائنًا يحتوي على الامتدادschemaوالتي يجب أن تحتوي على ملفمخططتعريف.

يجب أن نحدد المخطط أولاً!

إنشاءschema.jsملف ، وهناك نطلب أولاًgraphql، ثم استخدام ملفبناء جملة تدمير الكائننحصل علىGraphQLSchemaوGraphQLObjectTypeوGraphQLStringكائنات سنحتاج قريبًا إلى استخدامها:

const graphql = require('graphql')
const { GraphQLSchema, GraphQLObjectType, GraphQLString } = graphql

ثم نحدد قيمة المخطط من خلال تهيئة ملفGraphQLSchemaعلى سبيل المثال ، تمرير كائن يحتوي علىqueryمنشأه. هذه الخاصية هي مثيل لـGraphQLObjectTypeموضوع:

const schema = new GraphQLSchema({
  query: new GraphQLObjectType({
    //...
  }),
})

module.exports = schema

داخل هذا الكائن الجديد يجب أن نحدد أname، وأfieldsالعوامل. هذه الخاصية الأخيرة عبارة عن كائن يحتوي على مجموعة من الخصائص ، واحدة لكل حقل في مخططنا. في هذا المثال أنشأنا ملفhelloحقل:

const schema = new GraphQLSchema({
  query: new GraphQLObjectType({
    name: 'RootQueryType',
    fields: {
      hello: {
        type: GraphQLString,
        resolve() {
          return 'world'
        },
      },
    },
  }),
})

الresolve()طريقة إرجاع السلسلةworld، مما يعني أنه عندما نطلبhelloالمجال ، سوف نعيد تلك السلسلة.

هنا هو كاملschema.jsمحتوى الملف:

const graphql = require('graphql')
const { GraphQLSchema, GraphQLObjectType, GraphQLString } = graphql

const schema = new GraphQLSchema({ query: new GraphQLObjectType({ name: ‘RootQueryType’, fields: { hello: { type: GraphQLString, resolve() { return ‘world’ }, }, }, }), })

module.exports = schema

الآن دعنا نعود إلىapp.jsملف.

هذا ما كان لدينا:

const express = require('express')
const graphqlHTTP = require('express-graphql')

const app = express()

app.use(’/graphql’, graphqlHTTP())

app.listen(3000, () => { console.log(‘App listening on port 3000’) })

نحن الآن نطلبschema.jsملف:

const schema = require('./schema.js')

ونضيف ذلك في كائن نمرره إلىgraphqlHTTP()البناء:

app.use(
  '/graphql',
  graphqlHTTP({
    schema: schema,
  })
)

موافق!

يمكننا الآن اختبار هذا ومعرفة ما إذا كان يعمل. يمكننا ان نستخدمGraphiQL، أداة رائعة لاختبار واجهة برمجة تطبيقات GraphQL الخاصة بنا.

لقد تم تثبيته بالفعل ولتمكين ذلك ، نحتاج إلى تمرير خاصية أخرى إلىgraphqlHTTPالبناء:

app.use(
  '/graphql',
  graphqlHTTP({
    schema: schema,
    graphiql: true,
  })
)

الآن بعد أن تركضnode app.js، والوصول إلىhttp://localhost:3000/graphqlURL مع المتصفح سترى GraphiQL قيد التشغيل:

ويمكنك اختبار أول استدعاء لواجهة برمجة التطبيقات ، وتمرير هذا الاستعلام:

{
  hello
}

هذه هي النتيجة:

لنقم الآن ببناء مخطط أكثر تعقيدًا.

واحد يحتوي على أنواع متداخلة.

أحد الأمثلة التي يدور في بالي هو منشور مدونة.

تحتوي مشاركة المدونة على عنوان ووصف ، ولها أيضًا مؤلف. المؤلف له اسم.

دعونا نفهم هذا.

أولاً نضيف مجموعة المنشورات والمؤلفين:

const posts = [
  {
    title: 'First post',
    description: 'Content of the first post',
    author: 'Flavio',
  },
  {
    title: 'Second post',
    description: 'Content of the second post',
    author: 'Roger',
  },
]

const authors = { Flavio: { name: ‘Flavio’, age: 36, }, Roger: { name: ‘Roger’, age: 7, }, }

هذا هو المكان الذي سنحصل منه على البيانات.

Next, we define 3 GraphQLObjectTypeالأمثلة:

  • authorType، والذي يحدد بيانات المؤلف
  • postType، والتي تحدد بيانات النشر
  • queryType، الرئيسي

لنبدأ بالمؤلف. المؤلف له اسم وعمر.

نحن نستخدم الGraphQLIntالنوع الذي يجب أن نضيفه إلى الطلب

const { GraphQLSchema, GraphQLObjectType, GraphQLString, GraphQLInt } = graphql

//… const authorType = new GraphQLObjectType({ name: ‘Author’, fields: { name: { type: GraphQLString, }, age: { type: GraphQLInt, }, }, })

التالي هوpostType. المنشور له عنوان ووصف (كلا السلاسل) ومؤلف. المؤلف من النوعauthorType، التي حددناها للتو ، ولديها محلل.

نحصل على اسم المؤلف منsourceالمعلمة ، وهي المعلمات التي تم تمريرها إلى كائن post ، ونبحث عن بيانات المؤلف بناءً على ذلك. نعيده.

const postType = new GraphQLObjectType({
  name: 'Post',
  fields: {
    title: {
      type: GraphQLString,
    },
    description: {
      type: GraphQLString,
    },
    author: {
      type: authorType,
      resolve: (source, params) => {
        return authors[source.author]
      },
    },
  },
})

لاحظ أن وظيفة المحلل يمكن أن تكون غير متزامنة ، لذا يمكنك استخدام غير متزامن / انتظار للبحث عن الموارد من قاعدة بيانات أو من الشبكة.

التالي هو نوع الاستعلام ، نوع الجذر الذي سنضيفه إلى المخطط. هناك ، نحدد حقلين:

  • postمشاركة مدونة واحدة ، محددة بواسطة معرف
  • postsقائمة المشاركات

كلاهما لديه وظيفة محلل للبحث عن البيانات في ملفpostsمجموعة مصفوفة:

const queryType = new GraphQLObjectType({
  name: 'Query',
  fields: {
    post: {
      type: postType,
      args: {
        id: { type: GraphQLInt },
      },
      resolve: (source, { id }) => {
        return posts[id]
      },
    },
    posts: {
      type: new GraphQLList(postType),
      resolve: () => {
        return posts
      },
    },
  },
})

لاحظ الجديدGraphQLListالنوع الذي نستخدمه للالتفافpostTypeليعني أنها قائمةpostTypeشاء. يجب أن نطلبه في الأعلى:

const {
  GraphQLSchema,
  GraphQLObjectType,
  GraphQLString,
  GraphQLList,
  GraphQLInt,
} = graphql

هذا هو. نحن بحاجة إلى إضافته إلىschemaونحن على:

const schema = new GraphQLSchema({
  query: queryType,
})

ها هو الكود الكامل:

const graphql = require('graphql')
const {
  GraphQLSchema,
  GraphQLObjectType,
  GraphQLString,
  GraphQLList,
  GraphQLInt,
} = graphql

const posts = [ { title: ‘First post’, description: ‘Content of the first post’, author: ‘Flavio’, }, { title: ‘Second post’, description: ‘Content of the second post’, author: ‘Roger’, }, ]

const authors = { Flavio: { name: ‘Flavio’, age: 36, }, Roger: { name: ‘Roger’, age: 7, }, }

const authorType = new GraphQLObjectType({ name: ‘Author’, fields: { name: { type: GraphQLString, }, age: { type: GraphQLInt, }, }, })

const postType = new GraphQLObjectType({ name: ‘Post’, fields: { title: { type: GraphQLString, }, description: { type: GraphQLString, }, author: { type: authorType, resolve: (source, params) => { return authors[source.author] }, }, }, })

const queryType = new GraphQLObjectType({ name: ‘Query’, fields: { post: { type: postType, args: { id: { type: GraphQLInt }, }, resolve: (source, { id }) => { return posts[id] }, }, posts: { type: new GraphQLList(postType), resolve: () => { return posts }, }, }, })

const schema = new GraphQLSchema({ query: queryType, })

module.exports = schema

شاهد الكود الكامل على Glitch.


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