basis

GraphQL is a data query language developed by Facebook that many hope will replace the REST Api (REST Ful: Representational State Transfer table attribute State Transfer). Define urIs to retrieve resources through apis. An interface style that all languages can follow. .

GraphQL is both a query language for apis and a runtime for data queries. GraphQL can fetch data on demand through custom objects.

Features:

  • Request required data, no more, no less (multiple fields in a table, only one field request).
  • Get multiple resources and use one request of your own.
  • Describes all possible types of systems. Easy to maintain, smooth evolution according to requirements, add or hide fields.

Graph QL uses types to differentiate resources. Here is sample code:

var express = require('express')
var graphqlHTTP = require('express-graphql')
var { buildSchema } = require('graphql')
​
// Define schemas, queries, and types (query rules).
var schema = buildSchema('type Account{# Custom parameter type, corresponding to the Account type in Query Name: String age: Int, gender: String, department: String } type Query{ hello: String, accountName: String, age: Int, account: Account } `)
​
// Define the resolver corresponding to the query, that is, the handler corresponding to the query
var root = {
    hello: () = > { // Corresponds to the field in the schema
        return 'Hello world! '
    },
    accountName: () = > {
        return 'Zhang SAN Feng'
    },
    age: () = > {
        return 18
    },
    account: () = > {
        return {
            name: 'bill'.age: '18'.// The type is different from the one declared above, and GraphQL automatically converts it if it can. An error is reported when the conversion is not possible.
            gender: 'male'.department: 'IT',}}}var app = express()
app.use('/graphql',graphqlHTTP({
    schema: schema,
    rootValue: root,
    graphiql: true // Whether to enable the graphiQL debugging tool. It should be disabled when the project is online
}))
​
app.listen(4000)
Copy the code

Graphiql debugging screenshot in the browser:

Basic parameter types

  • Basic type (used directly when shema is declared)

    • String
    • Int
    • Float
    • Boolean
    • ID
  • An array of

    • [int] An array of integers.[type]).

Parameter passing

Similar to TS functions, you can pass arguments and declare types.

/ /! Indicates that this parameter is mandatorytype Query{ rollDice(numDice: Int! ,numSides: Int): [Int] }Copy the code

Sample code:

var schema = buildSchema(` type Query { getClassMates(classNo: Int!) : [String] } `)
​
// Define the handler for the query
var root = {
  getClassMates({ classNo }) {  // Object method, JS syntax sugar.
    const obj = {
      // simulate the database
      31: ['Joe'.'bill'.'Cathy'].61: ['Daisy'.'seven Chen'.'the old eight'],}return obj[classNo]
  },
}
Copy the code

Custom type

The first example code has custom types:

var schema = buildSchema(` type Account{ name: String age: Int, gender: String, department: String, salary(city: String): Int} type Query{getAccount(name: String): Account})
​
var root = {
  getAccount({ name }) {
      return {
          name: 'bill'.age: '18'.gender: 'male'.department: 'IT'.salary({ city }) {
          if (city === 'Beijing' || city === 'Shanghai') {
                return 10000
          } else {
              return 3000}}}}Copy the code

Graphiql debugging screenshot in the browser:

Each schema must have a Query, whether it is used or not

If there is no query in the schema, an error is reported as follows: Query root type must be provided.

Modify the data

Query is used for queries and mutation is used for changes to data. Here is the sample code:

// Define the schema, query, and type
var schema = buildSchema('Input AccountInput{name: String age: Int Gender: String department: String} type Account{name: String age: Int gender: String department: String} type Mutation{createAccount(input: AccountInput): Account updateAccount(id: ID! ,input: AccountInput): Account} type Query{accounts: [Account]} ')
​
const fakeDB = {}
​
// Define the handler for the query
var root = {
  accounts() {
    return Object.values(fakeDB)
  },
  createAccount({ input }) {
    // Save the database
    fakeDB[input.name] = input
    // Returns the save result
    return fakeDB[input.name]
  },
  updateAccount({ id, input }) {
    // Update the database
    const updateAccount = Object.assign({}, fakeDB[id], input)
    fakeDB[id] = updateAccount
    // Returns the save result
    return updateAccount
  },
}
Copy the code

Debug statements in graphiQL:

// Run the code section by section, annotating the other code before running. In graphiQL, the comment is #Mutation {# add operationcreateAccount(input:{
    name: "Bill",
    age: 19,
    gender: "Female",
    department: "IT"
  })Name age gender department}} query{# account accounts {name age gender department}} mutation{ # modify operationupdateAccount(id: "Zhang",input:{
    age: 18
  })The second object represents the return type age}}Copy the code

The above is the add, modify, and search usage of GraphQL. The delete operation can also be inferred from the above example.

Authority certification

Restrict urls that contain/graphQL.

const middleware = (req, res, next) = > {
  if (
    req.url.indexOf('/graphql')! = = -1&&...). { res.json({error: 'No permission to access this interface',})return
  }
  next()
}
app.use(middleware)
Copy the code

Constructing Types

Define type using GraphQLObjectType.

var schema = buildSchema(` input AccountInput{ name: String age: Int gender: String department: String } `)
// Use GraphQLObjectType to define type. The benefit is to know exactly what went wrong
var AccountType = new graphql.GraphQLOBjectType({
  name: 'Account'.fields: {
    name: { type: graphql.GraphQLString },
    age: { type: graphql.GraphQLInt },
    gender: { type: graphql.GraphQLString },
    department: { type: graphql.GraphQLString },
  },
})
​
Copy the code

Define query using GraphQLObjectType

var schema = buildSchema(` type Query{ accounts: [Account] } `)
​
// Use GraphQLObjectType to define query
var queryType = new graphql.GraphQLObjectType({
  name: 'Query'.fields: {
    account: {
      type: AccountType,
      args: {
        username: { type: graphql.GraphQLString }
      },
      resolve(_,{username}){
        return{
          name: username,
          gender: 'man'.age: 18.department: 'IT'}}}}})Copy the code

Create schema

var schema = new graphql.GraphQLSchema({ query: queryType })
Copy the code

Using the Constructing Types, you can obviously see more code, but the benefit is that the code is more maintainable.

Integrating with a database

In the code above, change the mutation handler operation on the object to the database operation.