简介
GraphQL 是一种由 Facebook 开发并开源的查询语言,用于 API 的高效数据获取。与传统的 RESTful API 不同,GraphQL 允许客户端精确指定所需的数据,从而减少数据传输量,提高性能,同时也简化了数据整合过程。
GraphQL的几个概念
Schema
在 GraphQL 中,Schema 是核心组件,它定义了数据模型、可用的操作类型(查询、突变、订阅)以及数据的访问规则。Schema 不仅描述了数据的结构,还定义了客户端如何与 API 进行交互。下面详细介绍 Schema 的概念及其使用方法:
Schema 的概念
- 类型定义:Schema 包含类型定义,如对象类型、接口类型、枚举类型、联合类型、标量类型和输入对象类型。每种类型都定义了其字段和字段的类型。
- 根类型:Schema 必须定义根类型,即
Query
、Mutation
和可选的Subscription
类型。这些根类型定义了客户端可以执行的操作。 - 字段解析器:对于 Schema 中的每个字段,都需要有对应的解析器来从数据源中获取数据。解析器可以是同步函数或异步函数。
- 指令:Schema 还支持自定义指令,这些指令可以修改解析器的行为,比如进行权限检查或数据转换。
定义 Schema
在 JavaScript 中,你可以使用 GraphQL 的 schema 定义语言(SDL)来定义 Schema。例如:
javascript
const { makeExecutableSchema } = require('graphql-tools');
const typeDefs = `
type Query {
hello: String
}
type Mutation {
greet(name: String!): String
}
`;
const resolvers = {
Query: {
hello: () => 'Hello world!',
},
Mutation: {
greet: (_, { name }) => `Hello ${name}!`,
},
};
const schema = makeExecutableSchema({
typeDefs,
resolvers,
});
使用 Schema
一旦 Schema 被定义,你就可以使用它来处理客户端的查询和突变。这通常涉及到创建一个 GraphQL 服务器,该服务器使用定义好的 Schema 来解析和执行来自客户端的请求。
javascript
const { ApolloServer } = require('apollo-server-express');
const express = require('express');
const server = new ApolloServer({ schema });
const app = express();
server.applyMiddleware({ app });
app.listen({ port: 4000 }, () =>
console.log(`🚀 Server ready at http://localhost:4000${server.graphqlPath}`)
);
实际应用拆解
fragment photoContent on PhotoEntity {
__typename
id
duration
}
fragment recoPhotoFragment on recoPhotoEntity {
__typename
id
duration
caption
}
fragment feedContent on Feed {
type
author {
id
name
}
photo {
...photoContent
...recoPhotoFragment
__typename
}
__typename
}
query visionSearch($keyword: String, $pcursor: String, $searchSessionId: String, $page: String, $webPageArea: String) {
visionSearch(keyword: $keyword, pcursor: $pcursor, searchSessionId: $searchSessionId, page: $page, webPageArea: $webPageArea) {
result
llsid
webPageArea
feeds {
...feedContent
__typename
}
searchSessionId
pcursor
aladdinBanner {
imgUrl
link
__typename
}
__typename
}
}
类型 (Types)
类型定义了数据的结构,它们可以是简单的标量类型如 String
或者 Int
,也可以是复杂的对象类型,如 PhotoEntity
和 Feed
。对象类型通常包含多个字段,每个字段都有其自己的类型。
PhotoEntity
和recoPhotoEntity
是两个对象类型,它们拥有相似的字段,如id
,duration
,caption
等。Feed
类型包含了author
,photo
,type
,canAddComment
等字段,其中author
和photo
字段又分别引用了User
和PhotoEntity
或recoPhotoEntity
类型。
变量 (Variables)
变量允许你在运行时向查询中注入动态值。在查询 visionSearchPhoto
中,使用了以下变量:
$keyword
: 用于搜索关键词。$pcursor
: 用于分页。$searchSessionId
: 用于跟踪搜索会话。$page
: 用于指定页面。$webPageArea
: 用于指定网页区域。
变量在查询字符串中通过 $
符号标记,并且在实际执行查询时需要提供一个变量对象来填充这些变量。
片段 (Fragments)
片段允许你定义可重用的查询模板,这在多个地方需要相同数据的情况下非常有用。在示例中,photoContent
和 recoPhotoFragment
是两个片段,它们包含了 PhotoEntity
和 recoPhotoEntity
类型的公共字段。feedContent
片段则包含了 Feed
类型的字段。
片段可以通过 ...
操作符添加到查询或子查询中,这样就可以避免在多个地方重复编写相同的字段列表。
查询 (Query)
查询是GraphQL中最常见的操作,用于从服务器获取数据。在给出的例子中,visionSearch
是一个查询,它接收多个变量并返回一系列 feeds
和其他相关数据。
查询定义了你想要从服务器获取的具体数据,而片段和类型则帮助定义了数据的结构。
GraphQL 的几个关键特性
- 类型系统:GraphQL 使用强类型的模式定义数据结构,这有助于客户端明确知道如何请求数据以及如何处理响应。类型系统包括标量类型(如字符串、整数)、枚举类型、接口、联合类型、对象类型和输入类型。
- 查询语言:GraphQL 提供了一个简洁的查询语言,允许客户端以声明式的方式请求数据。查询可以嵌套,以获取对象的属性和相关联的对象。
- 片段(Fragments) :片段是可复用的查询模板,可以包含在多个查询中,以避免重复代码。在给定的示例中,
photoContent
和recoPhotoFragment
就是用于PhotoEntity
和recoPhotoEntity
对象类型的片段,而feedContent
则是用于Feed
类型的片段。 - 变量(Variables) :GraphQL 支持在查询中使用变量,这些变量在执行查询时动态赋值。在示例中,
visionSearch
查询使用了$keyword
,$pcursor
,$searchSessionId
,$page
,$webPageArea
这些变量,它们在实际请求中会被具体的值替换。 - 执行模型:GraphQL 的执行模型允许服务器只返回请求的数据,没有额外的冗余信息。这减少了网络负载,提高了应用性能。
- 工具链:GraphQL 社区提供了丰富的工具链,包括 IDE 插件、代码生成器、服务器实现等,这些工具可以帮助开发者更高效地开发和调试 GraphQL 应用。