Getting started with GraphQL, Scheme and type

Posted by etully on Tue, 04 Jan 2022 13:04:45 +0100

https://www.yuque.com/books/share/ec8980d3-bf8c-4277-a96d-957455adf289?# (password: xume) GraphQL tutorial

GraphQL introduction

  • GraphQL is a data query language for API developed by Facebook and opened in 2015
  • GraphQL is not only a query language for API, but also a runtime to meet your data query.
  • GraphQL is an interface development standard that supports common server-side development languages. For example: Java, PHP, Python, node JS et al
  • Official website: https://graphql.org/
  • Chinese documents: https://graphql.cn/
  • GitHub: https://github.com/graphql
  • The future technology trend may replace RESTful, but it is not very good in recent years
    • Because RESTful precipitated for many years
    • A new project can all use GraphQL
    • GraphQL is used in conjunction with RESTful

Reference link

Getting started with GraphQL

GraphQL related support
see: https://graphql.org/code/.

  • back-end
  • client
  • tool
  • service

GraphQL.js
GraphQL.js is a reference implementation of graphql.

In order to process GraphQL queries, we need to define a schema of Query type. We also need an API root node to provide a function named resolver for each API endpoint. For return only Hello world! We can put this code in an API named server JS file:

const { graphql, buildSchema } = require('graphql')

// 1. Build a schema using GraphQL schema syntax
const schema = buildSchema(`
  type Query {
    hello: String
  }
`)

// 2. The root node provides a resolver function for each API entry endpoint
const root = {
  hello: () => {
    return 'Hello world!'
  }
}

// 3. Run graphql query '{Hello}', and output the response
graphql(schema, '{ hello }', root).then(response => {
  console.log(response) // Output result: {data: {Hello: 'hello world!'}}
})

Express GraphQL
In practice, you may not execute GraphQL in the command-line tool, but want to run GraphQL queries from an API server. For example, node js Express.

1. Installation dependency

npm install express express-graphql graphql

2. Sample code

const { buildSchema } = require('graphql')
const express = require('express')
const { graphqlHTTP } = require('express-graphql')
const cors = require('cors')

const app = express()

// Allow clients to cross domain requests
app.use(cors())

// 1. Build a schema using GraphQL schema syntax
const schema = buildSchema(`
  type Query {
    foo: String
    count: Int
  }
`)

// 2. Define resolver of scheme
const rootValue = {
  foo () {
    return 'bar'
  },
  count () {
    return 123
  }
}

// 3. Mount GraphQL Middleware
app.use('/graphql', graphqlHTTP({
  schema,
  rootValue,
  graphiql: true // Open the browser GraphQL IDE debugging tool
}))

// 4. Start the Web service
app.listen(4000, () => {
  console.log('GraphQL Server is running at http://localhost:4000/')
})

// 3. Query
// graphql(schema, '{ count, foo }', root).then(res => {
//   console.log(res)
// })

Summary:

  • The server specifies various forms of data that can be provided through the defined data types
  • The field of type should have a corresponding resolver to provide corresponding resolution
  • The client can selectively query the required field information according to the data type defined by the server

GraphQL client
With express GraphQL, you can send an HTTP POST request to the entry endpoint on the GraphQL server, where you can call the GraphQL server by taking the GraphQL query as the query field of the JSON payload.

An example of JavaScript request query is as follows:

 axios({
   method: 'POST', // The request method of GraphQL must be POST
   url: 'http://localhost:4000/graphql',
   data: {
     query: '{ foo, count }'
   }
 }).then(res => {
   console.log(res)
 })

GraphQL browser test tool

  • Opening mode
  • Basic use
    • to write
    • verification
    • test
  • Keyboard shortcuts
    • Format query: Shift-Ctrl-P
    • Merge query: Shift-Ctrl-M
    • Execute query: Ctrl enter
    • Autocomplete: Ctrl space
  • consult your documentation

GraphQL patterns and types

Query type

  • Strictly speaking, it is an object type
  • Is the entry point for all queries
  • Must be and cannot be repeated

Scalar type
The so-called scalar type is the basic type.

  • Int: signed 32-bit integer.
  • Float: signed double precision floating-point value.
  • String: UTF ‐ 8 character sequence.
  • Boolean: true or false.
  • ID: the ID scalar type represents a unique identifier, which is usually used to retrieve the object or as a key in the cache. ID type is serialized in the same way as String; However, defining it as an ID means that human readability is not required.

object type

  • In curly braces is the field information of the object
  • Attribute names are custom
  • The type after the property name is a scalar type built into GraphQL
  • GraphQL uses # annotations

List type

# This means that the array itself can be empty, but it cannot have any null value members.
myField: [String!]

# Non nullable string array
myField: [String]!

# The array itself cannot be empty, and the data in it cannot be empty
myField: [String!]!

Non empty type

  • By default, each type is nullable, which means that all scalar types can return null
  • An exclamation point can be used to mark a type, which cannot be empty, such as String! Represents a non empty String
  • If it is a list type, use square brackets to wrap the corresponding types. For example, [Int] represents a list of integers.

Enumeration type
Also known as enum, enum type is a special scalar, which is limited to a special set of optional values. This allows you to:

  1. Verify that any parameter of this type is one of the optional values
  2. In communication with the type system, a field is always one of the values of a finite set of values.
enum Episode {
  NEWHOPE
  EMPIRE
  JEDI
}
#This means that no matter where we use episod in the schema, we can be sure that it returns one of NEWHOPE, EMPIRE and JEDI.

Mutation type

  • Is the entry point for modification

Input type

  • Parameter objects must be defined using Input

Server side example:

/**
 * schema Type:
 *  - parameter
 *  - modify
 *  - Input type
 */

const { buildSchema } = require('graphql')
const express = require('express')
const { graphqlHTTP } = require('express-graphql')
const cors = require('cors')
const { v4: uuidv4 } = require('uuid')

const app = express()

app.use(cors())

const articles = [
  { id: '1', title: 'article 1', body: 'article 1 body' },
  { id: '2', title: 'article 2', body: 'article 2 body' },
  { id: '3', title: 'article 3', body: 'article 3 body' }
]

const schema = buildSchema(`
  type Article {
    id: ID!
    title: String!
    body: String!
    tagList: [String!]
  }

  # Entry point for query
  type Query {
    articles: [Article]
    article(id: ID!): Article
  }

  # Parameter objects must be defined using Input
  input CreateArticleInput {
    title: String!
    body: String!
    tagList: [String!]
  }

  input UpdateArticleInput {
    title: String!
    body: String!
  }

  type DeletionStatus {
    success: Boolean!
  }

  # Modify entry point
  type Mutation {
    createArticle(article: CreateArticleInput): Article
    updateArticle(id: ID!, article: UpdateArticleInput): Article
    deleteArticle(id: ID!): DeletionStatus
  }
`)

const rootValue = {
  articles () {
    return articles
  },
  article ({ id }) {
    return articles.find(article => article.id === id)
  },
  createArticle ({ article }) {
    article.id = uuidv4()
    articles.push(article)
    return article
  },
  updateArticle ({ id, article: postArticle }) {
    const article = articles.find(article => article.id === id)
    article.title = postArticle.title
    article.body = postArticle.body
    return article
  },
  deleteArticle ({ id }) {
    const index = articles.find(article => article.id === id)
    articles.splice(index, 1)
    return {
      success: true
    }
  }
}

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

app.listen(4000, () => {
  console.log('GraphQL Server is running at http://localhost:4000/')
})

Client example:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
  <script src="./node_modules/axios/dist/axios.js"></script>
  <script>
    axios({
      method: 'POST', // The request method of GraphQL must be POST
      url: 'http://localhost:4000/graphql',
      data: {
        query: `
          mutation deleteArteicle($id: ID!) {
            deleteArticle(id: $id) {
              success
            }
          }
        `,
        variables: {
          id: 2
        }
      }
    }).then(res => {
      console.log(res.data)
    })

    // Update article
    axios({
      method: 'POST', // The request method of GraphQL must be POST
      url: 'http://localhost:4000/graphql',
      data: {
        query: `
          mutation updateArteicle($id: ID!, $article: UpdateArticleInput) {
            updateArticle(id: $id, article: $article) {
              id
              title
              body
            }
          }
        `,
        variables: {
          id: 2,
          article: {
            title: 'aaa',
            body: 'bbb'
          }
        }
      }
    }).then(res => {
      console.log(res.data)
    })

    // Create article
    axios({
      method: 'POST', // The request method of GraphQL must be POST
      url: 'http://localhost:4000/graphql',
      data: {
        query: `
          mutation createArteicle($article: CreateArticleInput) {
            createArticle(article: $article) {
              id
              title
              body
            }
          }
        `,
        variables: {
          article: {
            title: 'aaa',
            body: 'bbb'
          }
        }
      }
    }).then(res => {
      console.log(res.data)
    })

    axios({
      method: 'POST', // The request method of GraphQL must be POST
      url: 'http://localhost:4000/graphql',
      data: {
        query: `
          query getArticles($id: ID!) {
            article(id: $id) {
              id
              title
            }
          }
        `,
        variables: {
          id: 2
        }
      }
    }).then(res => {
      console.log(res.data)
    })

    // Get a single article
    const id = 1
    axios({
      method: 'POST', // The request method of GraphQL must be POST
      url: 'http://localhost:4000/graphql',
      data: {
        query: `
          query getArticles {
            article(id: ${id}) {
              id
              title
            }
          }
        `
      }
    }).then(res => {
      console.log(res.data)
    })

    // Get article list
    axios({
      method: 'POST', // The request method of GraphQL must be POST
      url: 'http://localhost:4000/graphql',
      data: {
        query: `
        query getArticles {
          articles {
            title
          }
        }
        `
      }
    }).then(res => {
      console.log(res.data)
    })
  </script>
</body>
</html>

Topics: node.js graphql