GraphQL介绍&使用nestjs构建GraphQL查询服务

GraphQL介绍&使用nestjs构建GraphQL查询服务(文章底部附demo地址)

GraphQL一种用为你 API 而生的查询语言。出自于Facebook,GraphQL非常易懂,直接看查询语句就能知道查询出来的数据是什么样的。本质上属于API Layer层,负责前端请求的合并、数据整理等功能。

GraphQL介绍&使用nestjs构建GraphQL查询服务

查询示例

使用几个简单的例子看下GraphQL的查询是什么样子的。

普通查询

{
me {
name
}
}

查询出来的数据格式如下:

{
"me": {
"name": "wanghao"
}
}

1、返回来的数据是一个json

2、返回数据格式和查询完全一致

带参数的嵌套查询

入参格式:

{
user(id: 6) {
name,
profilePicture {
width,
height,
url
}
}
}

查询出来的数据如下:

{
"me" {
"name": "wanghao,"
"profilePicture": {
"width": 50,
"height": 50,
"url": "https://cdn/some.jpg"
}
}
}

当然,profilePicture查询时也可以指定参数:

{
me {
name,
profilePicture(size: 300) {
width,
height,
url
}
}
}

输出可能如下:

{
"me" {
"name": "wanghao,"
"profilePicture": {
"width": 300,
"height": 300,
"url": "https://cdn/300.jpg"
}
}
}

指定别名查询

有时候同一字段我们想要查询两次,但是两次指定的参数不同,比如一个用户有多张头像,我们只想查询其中的2张,可以如下:

{
me {
name,
littlePic: profilePicture(size: 50) {
width,
height,
url
},
bigPic: profilePicture(size: 300) {
width,
height,
url
}
}
}

输出结果如下:

{
"me" {
"name": "wanghao,"
"littlePic": {
"width": 50,
"height": 50,
"url": "https://cdn/50.jpg"
},
"bigPic": {
"width": 300,
"height": 300,
"url": "https://cdn/300.jpg"
}
}
}

更多查询请参考:http://graphql.cn/learn/queries/

变更

查询只适用于数据查询,但是往往接口还有部分新增、修改、删除操作,这个时候就需要使用变更(Mutations)。

想要新增一条数据,简单的变更入参如下:

mutation($inputComment: CommentInput!) {
addComment(data: $inputComment)
}

其中$inputComment是GraphQL中的变量写法,具体如下:

{
"inputComment": {
"postId": "5a796104fe9b131a10d9627d",
"text": "测试评论部分23232"
}
}

返回数据直接如下:

{
"data": {
"addComment": true
}
}

实际请求时的数据格式

GraphQL请求时不限制get、post请求,如果是get,会自动将请求体放在query中,看下实际请求时入参是什么样子的:

{
query: "mutation($inputComment: CommentInput!) {↵ addComment(data: $inputComment)↵}↵↵"
variables: "{↵ "inputComment": {↵"postId":"5a796104fe9b131a10d9627d",↵"text":"测试评论部分23232"↵}"
}

可以看出,请求时实际发送的是一串字符串至GraphQL服务器,GraphQL服务器会自动解析该字符串内容。

GraphQL可视化查询工具

GraphQL的所有实现基本都有实现该可视化工具,进行简单配置即可查看,express-graphql模块配置如下:

// GraphqQL server route
app.use('/graphql', graphqlHTTP(req => ({
schema,
pretty: true, // 配置显示pretty按钮进行代码美化
graphiql: true, // 配置开启可视化查询
})));

GraphQL介绍&使用nestjs构建GraphQL查询服务

GraphQL介绍&使用nestjs构建GraphQL查询服务

GraphQL介绍&使用nestjs构建GraphQL查询服务

dataloader

N+1查询问题

# 定义
type User {
name: String,
friends: [User]
} #查询
{
users {
name
friends {
name
friends {
name
}
}
}
}

GraphQL支持嵌套查询,如果没有dataloader,就会出现严重的N+1查询性能问题。

Dataloader(官方网址)是由facebook推出,能大幅降低数据库的访问频次,经常在Graphql场景中使用。

GraphQL介绍&使用nestjs构建GraphQL查询服务

import Sequelize from 'sequelize'
import DataLoader from 'dataloader' // 定义表结构
const sequelize = new Sequelize('test', null, null, {
dialect: 'sqlite',
})
const UserModel = sequelize.define('user', {
name: Sequelize.STRING
})
await sequelize.sync({force: true}) //插入测试数据
await [
UserModel.create({name: 'ron'}),
UserModel.create({name: 'john'}),
] // 初始化DataLoader,传入一个批处理函数
const userLoader = new DataLoader(keys => UserModel.findAll({where: {name: {$in: keys}}})) // 以下2个Load语句会被自动批处理,合并成一次数据库的操作
await [
userLoader.load('ron'),
userLoader.load('john')
]
Executing (default): SELECT id, name, createdAt, updatedAt FROM users AS user WHERE user.name IN ('ron', 'john’);

DataLoader缓存的典型应用是per-request范围的缓存,不能取代redis等应用级别的缓存。

使用nestjs构建GraphQL Server服务

nestjs,官网地址:https://docs.nestjs.com,是一个使用typescript构建nodejs后端应用的框架,类似java中的spring框架:依赖注入、拦截器、过滤器、装饰器模式等等,比较看好。

使用nestjs搭配GraphQL、typeorm、mysql实现了一个简单的GraphQL查询服务,查询支持单个查询、列表查询、关联查询,变更支持修改、删除操作,具体demo地址: https://github.com/caiya/graphql-nestjs-typeorm

上一篇:2D banner


下一篇:常见.NET功能代码汇总 (3)