简介
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 应用。