Cách tạo Máy chủ GraphQL với Node.js và Express

Hướng dẫn đơn giản về cách tạo máy chủ GraphQL hỗ trợ Node.js và Express

Bắt đầu bằng cách tạo một dự án Node.js mới, nếu bạn chưa thiết lập:

npm init --y

Lệnh này tạo rapackage.jsontệp chúng tôi cần làm việc vớinpm.

Cài đặt các gói npmexpress,graphqlexpress-graphql:

npm install express graphql express-graphql

Tạo ra mộtapp.jsvà hãy bắt đầu với việc khởi tạobày tỏngười phục vụ:

const express = require('express')

const app = express()

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

Bây giờ chúng tôi thêmexpress-graphql. Đây là mộtphần mềm trung gianvà chúng tôi chỉ áp dụng nó cho một tuyến đường,/graphqltuyến đường:

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

Chúng ta phải chuyển một đối tượng có chứaschemathuộc tính phải chứa mộtlược đồĐịnh nghĩa.

Chúng ta phải xác định một lược đồ trước!

Tạo mộtschema.jsvà trong đó trước tiên chúng tôi yêu cầugraphql, sau đó sử dụngcú pháp cấu trúc đối tượngchúng tôi nhận đượcGraphQLSchema,GraphQLObjectTypeGraphQLStringcác đối tượng mà chúng ta sẽ sớm cần sử dụng:

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

Sau đó, chúng tôi xác định giá trị giản đồ bằng cách khởi tạo mộtGraphQLSchemaví dụ, truyền một đối tượng có chứaquerybất động sản. Thuộc tính này là một ví dụ của mộtGraphQLObjectTypevật:

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

module.exports = schema

Bên trong đối tượng mới này, chúng ta phải chỉ định mộtname, và mộtfieldsthông số. Thuộc tính cuối cùng này là một đối tượng chứa một tập hợp các thuộc tính, một thuộc tính cho mỗi trường trong lược đồ của chúng ta. Trong ví dụ này, chúng tôi thiết lập mộthellocánh đồng:

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

Cácresolve()phương thức trả về chuỗiworld, có nghĩa là khi nào chúng tôi sẽ yêu cầuhellotrường, chúng tôi sẽ lấy lại chuỗi đó.

Đây là đầy đủschema.jsnội dung tệp:

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

Bây giờ chúng ta hãy quay trở lạiapp.jstập tin.

Đây là những gì chúng tôi đã có:

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

Bây giờ chúng tôi yêu cầuschema.jstập tin:

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

và chúng tôi thêm điều đó vào một đối tượng mà chúng tôi chuyển đếngraphqlHTTP()constructor:

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

Đồng ý!

Bây giờ chúng tôi có thể kiểm tra điều này và xem liệu nó có hoạt động hay không. Chúng ta có thể sử dụngGraphiQL, một công cụ tuyệt vời để kiểm tra API GraphQL của chúng tôi.

Nó đã được cài đặt và để kích hoạt điều đó, chúng tôi cần chuyển một thuộc tính khác chographqlHTTPconstructor:

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

Bây giờ sau khi bạn chạynode app.js, truy cập vàohttp://localhost:3000/graphqlURL với trình duyệt, bạn sẽ thấy GraphiQL đang hoạt động:

Và bạn có thể kiểm tra lệnh gọi API đầu tiên, chuyển truy vấn này:

{
  hello
}

Đây là kết quả:

Bây giờ chúng ta hãy xây dựng một lược đồ phức tạp hơn.

Một trong đó có các loại lồng nhau.

Một ví dụ mà tôi có trong đầu là một bài đăng trên blog.

Một bài đăng trên blog có tiêu đề, mô tả và nó cũng có tác giả. Tác giả có tên.

Hãy tìm hiểu điều này.

Đầu tiên, chúng tôi thêm tập hợp các bài đăng và tác giả:

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, }, }

Đây là nơi chúng tôi sẽ lấy dữ liệu từ đó.

Next, we define 3 GraphQLObjectTypecác trường hợp:

  • authorType, xác định dữ liệu tác giả
  • postType, xác định dữ liệu bài đăng
  • queryType, cái chính

Hãy bắt đầu với tác giả. Một tác giả có tên và tuổi.

Chúng tôi sử dụngGraphQLIntloại mà chúng ta phải thêm vào yêu cầu:

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

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

Tiếp theo làpostType. Một bài đăng có tiêu đề, mô tả (cả hai chuỗi) và tác giả. Một tác giả thuộc loạiauthorType, mà chúng tôi vừa xác định và nó có một trình phân giải.

Chúng tôi lấy tên tác giả từsourcetham số, là các tham số được truyền cho đối tượng bài đăng và chúng tôi tra cứu dữ liệu tác giả dựa trên đó. Chúng tôi trả lại nó.

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

Lưu ý rằng một chức năng phân giải có thể không đồng bộ, vì vậy bạn có thể sử dụng async / await để tra cứu tài nguyên từ cơ sở dữ liệu hoặc mạng.

Tiếp theo là queryType, kiểu gốc mà chúng ta sẽ thêm vào lược đồ. Trong đó, chúng tôi xác định 2 trường:

  • postmột bài đăng blog duy nhất, được xác định bởi một id
  • postsdanh sách các bài viết

cả hai đều có chức năng phân giải để tra cứu dữ liệu trongpostsmảng:

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

Chú ý cái mớiGraphQLListloại, mà chúng tôi sử dụng để bọcpostTypenghĩa là đó là danh sáchpostTypecác đối tượng. Chúng ta phải yêu cầu nó ở trên cùng:

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

Đó là nó. Chúng tôi cần thêm nó vàoschemavà chúng tôi đã thiết lập:

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

Đây là mã đầy đủ:

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

Xem mã hoàn chỉnh trên Glitch.


Các hướng dẫn về graphql khác: