GraphQL介绍&使用nestjs构建GraphQL查询服务
GraphQL介绍&使用nestjs构建GraphQL查询服务(文章底部附demo地址)
GraphQL一种用为你 API 而生的查询语言。出自于Facebook,GraphQL非常易懂,直接看查询语句就能知道查询出来的数据是什么样的。本质上属于API Layer层,负责前端请求的合并、数据整理等功能。
查询示例
使用几个简单的例子看下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, // 配置开启可视化查询
})));
dataloader
N+1查询问题
# 定义
type User {
name: String,
friends: [User]
}
#查询
{
users {
name
friends {
name
friends {
name
}
}
}
}
GraphQL支持嵌套查询,如果没有dataloader,就会出现严重的N+1查询性能问题。
Dataloader(官方网址)是由facebook推出,能大幅降低数据库的访问频次,经常在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
- 深入挖掘APP克隆实验
- Sickle:推荐一款优质ShellCode开发工具
- 看我教你如何修改QQ安装包实现绕过QQ语音红包验证来领红包
- “奇幻熊”(APT28)组织最新攻击
- GDB调试CVE-2018-5711 PHP-GD拒绝服务漏洞
- 高效与争议并存:大规模自动化渗透工具AutoSploit
- Android应用测试速查表
- ADB配置提权漏洞(CVE-2017-13212)原理与利用分析
- Fuzz自动化Bypass软WAF姿势
- Web黑盒渗透思路之猜想
- ZZCMS v8.2 最新版SQL注入漏洞
- 一款轻量级Web漏洞教学演示系统(DSVW)
- 使用Burpsuite代理和pypcap抓包进行抢红包的尝试
- 基于WAVSEP的靶场搭建指南
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 获取素材图无忧,Pixabay图库网Python多线程采集下载
- Python关键词数据采集案例,5118查询网站关键词数据采集
- Python结巴分词,字符串余弦相似度算法实现关键词筛选及整理
- git的分支远程连接和远程分支的拉取推送及冲突处理
- requests session的应用,python金点设计奖数据爬虫
- 站长工具关键词挖掘采集,Python关键词批量挖掘采集工具
- python百度关键词相关搜索词采集,链轮查询采集exe工具
- Python最火爬虫框架Scrapy入门与实践,豆瓣电影 Top 250 数据采集
- Python爬虫三种解析方式,Pyhton360搜索排名查询
- Python关键词百度指数采集,抓包Cookie及json数据处理
- 常用的package.json,还有这么多你不知道的骚技巧
- 【词库】Python关键词筛选分类,Levenshtein编辑距离算法分词
- 爬取数据缺失的补坑,Python数据爬取的坑坑洼洼如何铲平
- 如何开发跨框架的组件
- SpringBoot系列之异步任务@Async使用教程