专栏首页西安-晁州GraphQL介绍&使用nestjs构建GraphQL查询服务

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • js各种继承方式汇总

    js中的各种继承实现汇总 首先定义一个父类: function Animal(name) { this.name = name || '动物' this...

    用户1141560
  • struts2随笔

    1、struts.properties配置常量等同于struts.xml中配置(置于类加载路径下面) struts.multipart.maxSize文件上传最...

    用户1141560
  • nginx配置样例

    简单的nginx配置如下,包含了静态文件配置、websocket、socket.io的配置: user nobody; worker_processes 3;...

    用户1141560
  • 使用ASP.NET Core支持GraphQL -- 较为原始的方法

    下面是GraphQL的定义:  GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时。 GraphQL 对你的 API 中的数据提供了...

    solenovex
  • 大神修炼续,为自己搭建一个分布式 IM 系统二【从查找算法聊起】

    言归正传,上周更新了 cim 第一版:为自己搭建一个分布式的 IM 系统。没想到反响热烈,最高时上了 GitHubTrendingJava 版块的首位,一天收到...

    周萝卜
  • 领域驱动设计之聚合与聚合根实例二

    用户1910585
  • 设计输入设备的计算工作流程(CS HC)

    输入设备(例如按钮和滑块)是任何接口的基础。典型的以用户为中心的设计工作流程要求开发人员和用户经历设计、实施和分析的许多迭代。该过程效率低下,并且人为的决策会严...

    毛艺漩8078803
  • 【9】分页浏览的管理

    阅读目录 分页关注的内容 状态的传递 数据的获取 查询结果的分页 跳页的实现 分页器的样式 页面的完整处理流程 分页关注的内容 前面博文中,通过自...

    用户1075292
  • 同职位女员工薪酬高于男性?谷歌薪资调查受多方质疑

    每年3月8日临近,谷歌都会对员工薪酬进行分析,以确保公司中女性员工的薪酬不存在不公平。今年的调查结果却得出了一个惊人的结论:在做同类工作时,男员工的薪酬低于女员...

    大数据文摘
  • 不会查看系统源码,还搞什么Android?

    在上一篇文章如何方便快速的整编Android 9.0系统源码? )中,我们对系统源码进行了编译,这篇文章我们接着来学习如何将系统源码导入到编辑器中,以便于查看...

    Android技术干货分享

扫码关注云+社区

领取腾讯云代金券