Skip to content

GraphQL一种用于 API 的查询语言。示例代码仓库

  • 使用express和GraphQL
  • 参数类型和传递
  • GraphQL Client
  • 使用Mulations修改数据
  • 认证与中间件
  • 与数据库交互
  • Constructing Types

示例主要使用了express和express-graphqlmysql

下面的代码中演示了参数类型与参数的传递,mulations,中间件,和mysql的交互。constructing-types就是把type拆开来写,便于代码的维护,代码示例省略。

js
const express = require('express');
const { buildSchema } = require('graphql');
const graphqlHttp = require('express-graphql');

const mysql = require('mysql');
const connection = mysql.createConnection({
  host: 'localhost',
  user: 'root',
  password: 'root',
  database: 'my_db'
})

// String
// Int [Int]
// Float
// Boolean
// ID
const schema = buildSchema(`
  type Student {
    name: String
    age: Int
    address: String
    sno: String
    classNo: Int
    guote(q : String): String
  }
  input StudentInput {
    name: String
    age: Int
    address: String
    sno: String
    classNo: Int
  }
  type Mutation {
    createStudent(input: StudentInput): Student
  }
  type Query {
    hello: String
    getStudent(sno: String!): Student
    queryStudent: [Student]
  }
`)

const dbData = {
  student: [
    {
      name: 'Leslie',
      age: 18,
      sno: '201310119000',
      address: 'hubei',
      classNo: 11,
      guote ({ q }) {
        return `${this.classNo} class quote: ${q}`
      }
    },
    {
      name: 'Leo',
      age: 20,
      sno: '201310119001',
      address: 'hongkong',
      classNo: 11
    }
  ]
}

const rootValue = {
  hello () {
    return 'hello world!'
  },
  getStudent ({ sno }) {
    return dbData.student.find(it => it.sno === sno)
  },
  queryStudent () {
    return dbData.student
  },
  createStudent ({ input }) {
    // sql
    // return new Promise((resolve, reject) => {
    //   connection.query('insert into Student set ?', input, (err) => {
    //     if (err) {
    //       return
    //     }
    //     resolve(input)
    //   })
    // })
    dbData.student.push(input)
    return input
  }
}

const middleWare = (rep, res, next) => {
  // rep.headers.cooke.indexOf('auth') === -1
  if (rep.url.indexOf('/graphql') === -1) {
    return res.send(JSON.stringify({
      error: '403!'
    }))
  }
  next()
}

const app = express()

app.use(middleWare)

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

app.use(express.static('public'))

app.listen(3000)

如果想要频繁的改动重启项目,可使用nodemon【cnpm install -g nodemon】启动项目。 项目启动后,浏览器地址栏输入:http://localhost:3000/graphql会出现一个graphiQL的调试界面。 左侧的输入为:

json
query {
  hello
  getStudent(sno: "201310119000") {
    name
    age
    adress
    sno
    classNo
    guote(q: "好好学习,天天向上!")
  }
  queryStudent {
    name
    age
    adress
    sno
    classNo
  }
}

右侧的输出为:

json
{
  "data": {
    "hello": "hello world!",
    "getStudent": {
      "name": "Leslie",
      "age": 18,
      "adress": "hubei",
      "sno": "201310119000",
      "classNo": 11,
      "guote": "11 class quote: 好好学习,天天向上!"
    },
    "queryStudent": [
      {
        "name": "Leslie",
        "age": 18,
        "adress": "hubei",
        "sno": "201310119000",
        "classNo": 11
      },
      {
        "name": "Leo",
        "age": 20,
        "adress": "hongkong",
        "sno": "201310119001",
        "classNo": 11
      }
    ]
  }
}

验证mutation,左侧输入:

json
mutation {
  createStudent(input: {
    name: "jack"
    sno: "201310119002"
    address: "shanghai"
    classNo: 7
  }) {
    name
    address
    sno
    classNo
  }
}

右侧输出:

json
{
  "data": {
    "createStudent": {
      "name": "jack",
      "address": "shanghai",
      "sno": "201310119002",
      "classNo": 7
    }
  }
}

增加一个graphql clients:

html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>GraphQL_Client</title>
</head>
<body>
  <button onclick="getJSON()">Get JSON</button>
</body>
<script>
    function getJSON() {
      const query = `
        query GetStudent($sno: String!) {
          getStudent(sno: $sno) {
            name
            address
            age
            classNo
          } 
        }
      `

      const variables = {
        sno: "201310119000"
      }

      fetch('/graphql', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json'
        },
        body: JSON.stringify({
          query,
          variables
        })
      })
      .then(resp => resp.json())
      .then(json => {
        console.error(json)
      })
    }
</script>
</html>

点击按钮,输出的数据为:

json
{
  "data": {
    "getStudent": {
      "name":"Leslie",
      "address":"hubei",
      "age":18,
      "classNo":11
    }
  }
}

Powered by VitePress.