前言
在日常开发中,我们普遍使用的是RESTful API接口。不过偶尔我们也能在某些网站上发现GraphQL的身影,比如 Facebook, Github, leetcode.cn 等网站。在Nest项目中,我们通过引入 @nestjs/graphql, @nestjs/apollo, graphql,就能快速地进行 GraphQL 接口的开发和测试。
本文介绍了GraphQL的常用语法。
GraphQL是什么
官网介绍如下:
GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.
GraphQL 是 Facebook 于 2015 年开源的一种用于生成 API 的查询语言。相比于 RESTful API,具有以下优点:
- 定制化 API 字段,按需取字段
- 一次请求,获取所有数据
- 后端不再需要维护不同版本的接口了
- 接口更健壮,具有完备的类型校验机制和字段描述
GraphQL 如何使用呢?在开发对应的后端接口后,我们需要编写 query 语句和 mutation 进行增删查改操作。
query 语句
在书写 query 查询语句时,query关键词和query名字都可以省略,也可以只省略query名字。
我们写上所需的字段,可以看到查询结果就只包含了所需字段。
此外,query语句也能包含注释。
query {
{
user {
name
# 这是注释语句~
friends {
name
}
}
}
}
{
"data": {
"user": {
"name": "hhh",
"friends": [
{
"name": "a1"
},
{
"name": "a2"
},
{
"name": "a3"
}
]
}
}
}
如果我们想查询 id 为1000的用户,传参即可实现:
{
user(id: "1000") {
name
height
}
}
{
"data": {
"user": {
"name": "a1",
"height": 1.72
}
}
}
如果我们想同时查询 id 为 1和2的两个用户,可以借助别名:
{
a: user(id: 1) {
name
}
b: user(id: 2) {
name
}
}
{
"data": {
"a": {
"name": "aaa"
},
"b": {
"name": "bbb"
}
}
}
此外,GraphQL支持定义变量:
query UserNameAndFriends($user: User) {
hero(user: $user) {
name
friends {
name
}
}
}
// 定义变量值:
{
"user": "Tom"
}
mutation 语句
mutation 语句和query语句类似,以关键字 mutation 开始,可以设置返回值,也可以不设置。比如我们定义了一个新增文章的接口,代码如下:
mutation{
addArticle(title: "aa", author: "Jack")
}
mutation{
addArticle(id: 1, title: "aaa", author: "Jack"){
id
title
author
}
}
schema, type, input
一般情况下,我们会在 xxx.graphql 文件中定义 schema。在 graphql 文件中,使用 type 关键字定义了 query语句、mutation语句等。
举个例子,下面是 cats.graphql 文件的内容,其中我们定义了类型 Cat, Owner 的字段名,以及对应的query语句、mutation语句等。
可以在"""符号中添加相应的注释文字。
type Query {
cats: [Cat]
cat(id: ID!): Cat
}
type Mutation {
createCat(createCatInput: CreateCatInput): Cat
}
type Subscription {
catCreated: Cat
}
type Owner {
id: Int!
name: String!
age: Int
cats: [Cat!]
}
type Cat {
id: Int
name: String
age: Int
owner: Owner
}
"""
Test comment
"""
input CreateCatInput {
name: String
age: Int
}
代码中我们还发现了新的 input 关键字,这是什么意思?
根据官网,我们可知 type 对象不适合于复用的情况,因为 对象可能包含循环引用或者对于接口或者 union 的引用。这种情况下应该使用 input 。
The Object type defined above is inappropriate for re‐use here, because Objects can contain fields that express circular references or references to interfaces and unions, neither of which is appropriate for use as an input argument. For this reason, input objects have a separate type in the system.
后记
本文只是浅浅地探索了 GraphQL 的相关用法。
GraphQL 在全栈开发中有着光明的前景!学习 Nest,离不开对 GraphQL 接口的学习。在掌握了 GraphQL 这门语言后,我们可以方便、快捷地进行接口的开发和联调工作。