- 原文地址:A Beginner’s Guide to GraphQL
- 原文做者:Leonardo Maldonado
- 项目仓库:GraphQL-Guide-For-Beginner
- 译者:Seymoe
- 译者注:此文为本人第一篇译文,本人做为无 GraphQL 使用背景的初学者,翻译过程亦是学习过程。若是发现译文有错误或者表述不当的地方敬请指正,十分感谢!
API 是互联网行业讨论最多的术语之一,可是不少人并不确切知道 API 究竟是什么。基本上,API 表明应用程序编程接口(Application Programming Interface)。顾名思义,它至关于一个“界面”,令人们(开发人员、用户、消费者)可以经过它与数据进行交互。php
你能够理解为 API 就像是个酒保,你向酒保要一杯酒,他便把一杯你想要的酒递给你,看起来很简单的事,还有什么问题呢?git
构建 API 不是一件困难的事,但学习和理解具体的 API 可能存在必定的困难。多数开发者都会使用你的 API 去开发功能或者只是消费数据,这就要求 API 须要尽量保持干净、直观。精心设计、直观性强的 API 会很是容易理解和使用。github
一直以来,咱们都在用 REST 来构建 API,使用这种方式会存在一些问题,例如:数据库
为了解决以上的相似问题,Facebook 创造了 GraphQL。我认为 GraphQL 是当代构建 API 的最佳方式,本文将阐述为何你应该开始学习 GraphQL,让你了解 GraphQL 的工做原理,以及如何使用 GraphQL 建立设计精良、高效而且功能强大的 API。npm
你可能已经据说过 GraphQL,由于不少开发者和公司都在使用它。因为 GraphQL 是开源的,因此社区也是很庞大的存在。让咱们在实践中学习 GraphQL 的工做原理,领略它的魔力了。编程
GraphQL (译者注:中文文档)是 Facebook 开发的一种开源查询语言。它为咱们提供了一种更有效的方式来设计、建立和消费咱们的 API 。基本上,它是 REST 的替代品。json
GraphQL 有不少功能,例如:数组
这是对 GraphQL 的基本介绍,解释了为何它如此强大以及为何它现在得到了不少人气。若是想了解更多相关信息,我建议访问 GraphQL 网站去了解。浏览器
本文主要目的不是学习如何配置 GraphQL 服务器,因此咱们如今不会深刻研究。本文的目标是了解 GraphQL 在实践中的工做原理,所以咱们将使用一个叫作☄️Traderpack的零配置GraphQL服务器库。bash
第一步,咱们须要建立一个新文件夹,你能够随意命名。我将它命名为 graphql-server :
mkdir graphql-server
复制代码
假定你已经在本身的机器中安装了 npm 或 yarn。若是你不知道它们是什么,npm 和 yarn 是 JavaScript 编程语言的包管理器。对于 Node.js,默认包管理器是 npm。
在建立的文件夹中,输入如下命令:
npm init -y
复制代码
若是你使用 yarn :
yarn init
复制代码
npm 会建立一个 package.json
文件,项目安装的全部依赖项和命令都在这个文件中。
接下来,咱们来安装本项目要使用的惟一依赖项,☄️Traderpack 容许你建立零配置的 GraphQL 服务器。因为咱们刚刚开始使用 GraphQL,这将帮助咱们继续学习更多内容,而没必要担忧服务器配置。
打开终端进入项目文件夹,键入如下命令:
npm install --save-dev graphpack
复制代码
若是你使用 yarn,应该这样:
yarn add --dev graphpack
复制代码
安装 Graphpack 以后,转到 package.json
文件中的脚本,并在其中输入如下代码:
"scripts": {
"dev": "graphpack",
"build": "graphpack build"
}
复制代码
咱们将建立一个名为 src 的文件夹做为整个服务器中惟一的文件夹,而后在 src 文件夹中建立三个文件。
译者注:使用 VSCode 的童鞋能够安装 `GraphQL for VSCode` 插件进行语法高亮
首先,咱们建立第一个文件,名叫 schema.graphql
,并在这个文件中输入如下代码:
type Query {
hello: String
}
复制代码
这个 schema.graphql
文件将是咱们的整个 GraphQL 架构,稍后我会解释它的做用。
接下来,在 src 文件夹中建立第二个文件 resolvers.js
,并在这个文件中输入如下代码:
import { users } from "./db"
const resolvers = {
Query: {
hello: () => "Hello World!"
}
}
export default resolvers
复制代码
这个 resolvers.js
文件将是咱们提供将 GraphQL 操做转换为数据的指令的方式。
最后,在src文件夹中建立第三个文件 db.js
,并在这个文件中输入如下代码:
export let users = [
{ id: 1, name: "John Doe", email: "john@gmail.com", age: 22 },
{ id: 2, name: "Jane Doe", email: "jane@gmail.com", age: 23 }
]
复制代码
在本教程中,咱们没有使用真实数据库。因此这个 db.js
文件将模拟数据库,仅用于学习目的。
如今咱们的src文件夹应以下所示:
src
|--db.js
|--resolvers.js
|--schema.graphql
复制代码
如今,若是你运行命令 npm run dev
,或者若是你正在使用yarn,则运行 yarn dev
,应该在终端中看到此输出:
如今能够用浏览器打开 localhost:4000
,这意味着咱们已准备好开始在 GraphQL 中编写咱们的第一个 queries(查询),mutations(突变)和 subscriptions(订阅)。
若是感兴趣能够看看 GraphQL Playground,这是一个功能强大的 GraphQL IDE,可用于更好的开发工做流程。若是你想了解有关 GraphQL Playground 的更多信息,请单击此处。
GraphQL 有本身的语言类型,用于编写 Schema(模式)。这是一种人类可读的模式语法,称为 Schema Definition Language - 模式定义语言(SDL)。不管使用何种技术,SDL都是相同的 - 你能够将其用于你想要的任何语言或框架。这种模式语言很是有用,由于它会让你很容易直观的理解你的 API 将具备哪些类型。
Types(类型)是 GraphQL 最重要的特性之一。Types 是自定义对象,表示 API 的外观。举个例子,若是你正在构建社交媒体应用程序,那么你的 API 可能会有 Posts
、Users
、Likes
、Groups
等 Types。
Types 下有 fields(字段),这些字段返回特定类型的数据。例如,咱们要建立一个 User 类型,咱们应该有 name
、email
和 age
等字段。字段能够是任何类型,并始终返回一种数据类型,好比 Int、Float、String、Boolean、ID、对象类型列表或自定义对象类型。
如今编写咱们的第一个 Type,转到 schema.graphql
文件并用如下内容替换已存在的 Query
类型:
type User {
id: ID!
name: String!
email: String!
age: Int
}
复制代码
每一个 User
都将拥有一个 ID
,所以咱们为其提供了 ID
类型。User
也会有一个 name
和 email
,因此咱们给它们 String
类型,年龄咱们给了 Int
类型。很简单吧?
数据类型后面的 !
表示该字段非空(non-nullable),这意味着这些带 !
的字段必须在每一个查询中返回一些数据。
在 GraphQL 中有三个主要概念:
这三个主要概念我会一一解释。
简单来讲,GraphQL 中的查询就是获取数据的方式。GraphQL 中的查询会得到所需的确切数据。很少也很多。这对咱们的 API 产生了巨大的积极影响 - 再也不像咱们使用 REST API 那样过分获取或提取不足信息。
让咱们来中建立一个查询类型,首先,在 schema.graphql
中添加一个名为 Query
的新类型:
type Query {
users: [User!]!
}
复制代码
users
查询将返回给咱们一个或多个用户的数组。它不会返回 null
,由于咱们在后面加了 !
,这意味着它是一个不可为空的查询,应该老是返回一些东西。
既然能返回多个,咱们也能返回一个特定用户,在 Query
类型中添加一个新的查询 user
:
type Query {
users: [User!]!
+ user(id: ID!): User!
}
复制代码
你会发现查询可以传递参数,查询特定用户的时候把用户的 id
做为参数传入。
那么 GraphQL 如何知道去哪获取到数据返回呢?这就是 resolvers.js
的做用,它会告诉 GraphQL 如何以及在何处获取数据。
打开 resolvers.js
文件,更改一下代码:
import { users } from "./db"
const resolvers = {
Query: {
user: (parent, { id }, context, info) => {
return users.find(user => user.id === id)
},
users: (parent, args, context, info) => {
return users
}
}
}
export default resolvers
复制代码
解释一下以上代码是如何工做的:
user
函数中,咱们将 id
做为参数传递,而后返回与传递的 id
匹配的特定用户users
函数中,咱们只是返回已存在的 users
数组,它会返回全部的用户如今,咱们将测试咱们的查询是否正常工做。浏览器打开 localhost:4000
,在左边输入如下代码而后点运行按钮:
query {
users {
id
name
email
age
}
}
复制代码
试试返回 id 为 1 的用户:
query {
user(id: 1) {
id
name
email
age
}
}
复制代码
在 GraphQL 中,Mutations 是修改服务器上的数据并获取更新数据的方式。你能够理解为相似 REST 的CUD(CREATE,UPDATE,DELETE)。
咱们来建立一个类型突变,咱们全部的突变都将在这种类型中结束。在 schema.graphql
文件中编写一个名为 mutation
的新类型:
type Mutation {
createUser(id: ID!, name: String!, email: String!, age: Int): User!
updateUser(id: ID!, name: String, email: String, age: Int): User!
deleteUser(id: ID!): User!
}
复制代码
上述代码建立了三个 Mutation:
createUser
- 咱们传入的参数 id
、name
、email
、age
,应该返回一个新的用户updateUser
- 传入 id
和新的 name
、email
与 age
, 应该返回一个更新后的用户deleteUser
- 传入 id
,应该返回被删除掉用户的信息如今,咱们去 resolvers.js
文件中,在 Query
对象下方插入一个新的 Mutation
对象。
Mutation: {
createUser: (parent, { id, name, email, age }, context, info) => {
const newUser = { id, name, email, age }
users.push(newUser)
return newUser
},
updateUser: (parent, { id, name, email, age }, context, info) => {
let newUser = users.find(user => user.id === id)
newUser.name = name
newUser.email = email
newUser.age = age
return newUser
},
deleteUser: (parent, { id }, context, info) => {
const userIndex = users.findIndex(user => user.id === id)
if (userIndex === -1) throw new Error("User not found.")
const deletedUsers = users.splice(userIndex, 1)
return deletedUsers[0]
}
}
复制代码
该去 localhost:4000
看看咱们写的 Mutations 是否有效了,在页面上输入:
mutation {
createUser(id: 3, name: "Robert", email: "robert@gmail.com", age: 21) {
id
name
email
age
}
}
复制代码
你也能够尝试一下其余的 Mutation。
正如我以前所说,Subscriptions (订阅)是你与服务器保持实时链接的方式。这意味着不管什么时候在服务器中发生事件,而且每当调用该事件时,服务器都会将相应的数据发送到客户端。经过使用订阅,你能够将应用程序更新为不一样用户之间的最新更改。
最基本的订阅示例:
subscription {
users {
id
name
email
age
}
}
复制代码
你会说它与查询很是类似,但它的工做方式和查询不一样。当服务器中的某些内容更新时,服务器将运行订阅中指定的 GraphQL 查询,并将更新的结果发送到客户端。我并不打算在这篇文章中使用订阅,但若是你想了解更多关于它们的信息,请点击此处。
如你所见,GraphQL 是一项很是强大的新技术。它为咱们提供了构建更好和精心设计的 API 的真正能力。这就是为何我建议你如今开始学习它。
对我来讲,它最终将取代 REST。
感谢阅读文章,请在下面发表评论!