前言
本来这篇文章准备51假期期间就发出来的,但是因为自己的笔记本电脑出了一点问题,所以拖到了现在😂。为了大家更好的学习GraphQL,我写一个前后端的GraphQL的Demo,包含了登陆,增加数据,获取数据一些常见的操作。前端使用了Vue和TypeScript,后端使用的是Koa和GraphQL。
这个是预览的地址: GraphQLDeom 默认用户root,密码root
GraphQL入门以及相关概念
什么是GraphQL?
按照官方文档中给出的定义, "GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时。 GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述,使得客户端能够准确地获得它需要的数据,而且没有任何冗余,也让 API 更容易地随着时间推移而演进,还能用于构建强大的开发者工具"。但是我在使用之后发现,gql需要后端做的太多了,类型系统对于前端很美好,但是对于后端来说可能意味着多次的数据库查询。虽然gql实现了http请求上的优化,但是后端io的性能也应当是我们所考虑的。
查询和变更
GraphQL中操作类型主要分为查询和变更(还有subscription订阅),分别对应query,mutation关键字。query,mutation的操作名称operation name是可以省略的。但是添加操作名称可以避免歧义。操作可以传递不同的参数,例如getHomeInfo中分页参数,AddNote中笔记的属性参数。下文中,我们主要对query和mutation进行展开。
query getHomeInfo {
users(pagestart: ${pagestart}, pagesize: ${pagesize}) {
data {
id
name
createDate
}
}
}
mutation AddNote {
addNote(note: {
title: "${title}",
detail: "${detail}",
uId: "${uId}"
}) {
code
}
}
Schema
全称Schema Definition Language。GraphQL实现了一种可读的模式语法,SDL和JavaScript类似,这种语法必须存储为String格式。我们需要区分GraphQL Schema和Mongoose Schema的区别。GraphQL Schema声明了返回的数据和结构。Mongoose Schema则声明了数据存储结构。
类型系统
标量类型
GraphQL提供了一些默认的标量类型, Int, Float, String, Boolean, ID。GraphQL支持自定义标量类型,我们会在后面介绍到。
对象类型
对象类型是Schema中最常见的类型,允许嵌套和循环引用
type TypeName {
fieldA: String
fieldB: Boolean
fieldC: Int
fieldD: CustomType
}
查询类型
查询类型用于获取数据,类似REST GET。Query是Schema的起点,是根级类型之一,Query描述了我们可以获取的数据。下面的例子中定义了两种查询,getBooks,getAuthors。
type Query {
getBooks: [Book]
getAuthors: [Author]
}
getBooks,获取book列表
getAuthors,获取作者的列表
传统的REST API如果要获取两个列表需要发起两次http请求, 但是在gql中允许在一次请求中同时查询。
query {
getBooks {
title
}
getAuthors {
name
}
}
突变类型
突变类型类似与REST API中POST,PUT,DELETE。与查询类型类似,Mutation是所有指定数据操作的起点。下面的例子中定义了addBook mutation。它接受两个参数title,author均为String类型,mutation将会返回Book类型的结果。如果突变或者查询需要对象作为参数,我们则需要定义输入类型。
type Mutation {
addBook(title: String, author: String): Book
}
下面的突变操作中会在添加操作后,返回书的标题和作者的姓名
mutation {
addBook(title: "Fox in Socks", author: "Dr. Seuss") {
title
author {
name
}
}
}
输入类型
输入类型允许将对象作为参数传递给Query和Mutation。输入类型为普通的对象类型,使用input关键字进行定义。当不同参数需要完全相同的参数的时候,也可以使用输入类型。
input PostAndMediaInput {
title: String
body: String
mediaUrls: [