GraphQL 是什么
Facebook 开发的一种数据查询语言
GraphQL 使用 Schema 来描述数据,并通过制定和实现 GraphQL 规范定义了支持 Schema 查询的 DSQL (Domain Specific Query Language,领域特定查询语言,由 FACEBOOK 提出。
特点
- 请求需要的数据,不多不少,只取得需要的字段
- 获取多个资源,只用一个请求
- 描述所有可能类型的系统。便于维护,根据需求平滑演进,添加或者隐藏字段。
GraphQL 和 Restful 对比
- Restful 一个接口只能返回一个资源,GraphQL 一次可以获取多个资源。
- Restful 用不同的 url 来区分资源,GraphQL 用类型区分资源。
实例
const express = require('express');const { buildSchema } = require('graphql');const grapqlHTTP = require('express-graphql');// 定义 schema,查询和类型const schema = buildSchema(`type Query {hello: String,accountName: String,}`);// 定义查询对应的处理器const root = {hello() {return 'hello world';},accountName() {return '张三';}};const app = express();app.use('/graphql', grapqlHTTP({schema: schema,rootValue: root,graphiql: true}));app.listen(3000);
基本参数类型
基本数据类型:String、Int、Float、Boolean、ID,都可以在 shema 声明。
参数传递
- 和 JavaScript 传递参数一样,小括号内定义形参,但是注意:参数需要定义类型。
- !(叹号)代表参数不能为空。
type Query {rollDice(numDice: Int!, numSides: Int): [Int]}
const express = require('express');const { buildSchema } = require('graphql');const grapqlHTTP = require('express-graphql');// 定义 schema,查询和类型const schema = buildSchema(`type Query {getClassMates(classNo:Int!): [String]}`);// 定义查询对应的处理器const root = {getClassMates({ classNo }) {const obj = {32: ['小明', '小李', '小鱼'],61: ['大三', '大力', '大开'],};return obj[classNo];}};const app = express();app.use('/graphql', grapqlHTTP({schema: schema,rootValue: root,graphiql: true}));app.listen(3000);
自定义参数类型
const express = require('express');const { buildSchema } = require('graphql');const grapqlHTTP = require('express-graphql');// 定义 schema,查询和类型const schema = buildSchema(`type Account {name: Stringage: Intsex: Stringdepartment: Stringsalary(city: String): Int}type Query {getClassMates(classNo: Int!): [String]account(username: String): Account}`);// 定义查询对应的处理器const root = {getClassMates({ classNo }) {const obj = {32: ['小明', '小李', '小鱼'],61: ['大三', '大力', '大开'],};return obj[classNo];},account({ username }) {const name = username;const sex = '男';const age = 18;const department = '开发部';const salary = ({ city }) => {if( city === '上海' ) {return 10000;}return 4000;};return {name,age,sex,department,salary}}};const app = express();app.use('/graphql', grapqlHTTP({schema: schema,rootValue: root,graphiql: true}));app.listen(3000);

前端调用 GraphQL 接口
public/index.html
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>graphqQL</title></head><body><button id="getQuery">获取数据</button><script>const button = document.querySelector('#getQuery');button.addEventListener('click',() => {const query = `query Account($username: String) {account(username: $username) {nameagesexsalary(city: "北京")}}`;const variables = { username: '李大四' };fetch('/graphql', {method: 'post',headers: {'Content-Type': 'application/json','Accent': 'application/json',},body: JSON.stringify({query,variables,})}).then(res=>res.json).catch(e=>{console.log(e);})});</script></body></html>
helloGraphQL.js
const express = require('express');const { buildSchema } = require('graphql');const grapqlHTTP = require('express-graphql');// 定义 schema,查询和类型const schema = buildSchema(`type Account {name: Stringage: Intsex: Stringdepartment: Stringsalary(city: String): Int}type Query {getClassMates(classNo: Int!): [String]account(username: String): Account}`);// 定义查询对应的处理器const root = {getClassMates({ classNo }) {const obj = {32: ['小明', '小李', '小鱼'],61: ['大三', '大力', '大开'],};return obj[classNo];},account({ username }) {const name = username;const sex = '男';const age = 18;const department = '开发部';const salary = ({ city }) => {if( city === '上海' ) {return 10000;}return 4000;};return {name,age,sex,department,salary}}};const app = express();app.use('/graphql', grapqlHTTP({schema: schema,rootValue: root,graphiql: true}));app.use(express.static('public'));app.listen(3000);
Mutation
const express = require('express');const { buildSchema } = require('graphql');const grapqlHTTP = require('express-graphql');// 定义 schema,查询和类型const schema = buildSchema(`input AccountInput {name: Stringage: Intsex: Stringdepartment: String}type Account {name: Stringage: Intsex: Stringdepartment: String}type Mutation {createAccount(input: AccountInput): AccountupdateAccount(id: ID!, input: AccountInput): Account}type Query {account: [Account]}`);const fakeDB = {};// 定义查询对应的处理器const root = {accounts(){var arr = [];for (let key in fakeDB) {arr.push(fakeDB[key]);}return arr;},createAccount({ input }) {// 相当于数据库的保存fakeDB[input.name] = input;return fakeDB[input.name]},updateAccount({ id, input }) {// 相当于数据库的更新Object.assign({}, fakeDB[id], input);fakeDB[id] = updateAccount;return updateAccount;}};const app = express();app.use('/graphql', grapqlHTTP({schema: schema,rootValue: root,graphiql: true}));app.listen(3000);
与数据库结合使用
参考
【1】GraphQL-js 中文网
【2】解析 GraphQL 的查询语法【译】| 前端外刊评论
【3】GraphQL 从入门到实践
【4】GraphQL 入门到精通(视频)
【5】GraghQL初探(一) | 奇舞周刊
【8】GraphQL 学习:Github GraphQL API v4 初探
【9】搭建你的第一个 GraphQL 服务器
【10】GraphQL-前端开发的利剑与桥梁
