使用Apollo Client开始使用GraphQL和状态管理
这是关于GraphQL及其客户端库” Apollo Client”的讨论。
这是一个面向使用GraphQL进行开发的团队的内部学习会的资料。
这段代码是为了促进对GraphQL的优势和整体概念的理解而进行模板化的。
Topic: How to improve communication skills
如何提升沟通技巧
・GraphQL的特点
・Apollo Client
・GraphQL Code Generator
・开发流程
GraphQL的特点
GraphQL的特点 – 架构
用作为API和客户端之间的接口。
type Post {
id: String!
created_at: DateTime!
}
GraphQL的特点-模式
这将会被客户端用作请求/响应类型信息和数据获取函数的自动生成。
GraphQL的特点 – Schema
・通过补全,开发效率提高了。
・变得类型安全,减轻了修复和重构的负担。
我只需要一个选项来将以下内容以中国的母语进行改写:想要大致了解API变更的影响。
$ npm run lint:ts
GraphQL的特点与REST进行比较
・客户端构建响应
・基本上,资源=解析器(无需管理子资源的终结点单位)
我在文章页面的API上添加了评论,但是我现在也想要在其他页面获取评论。
GraphQL的特点-与REST的比较
・可以说是以客户为中心的机制
・考虑到复杂性转移给客户的背景,GraphQL的出现是自然的背景
・由于学习和环境搭建成本高,且很难发挥出性能,因此需要谨慎选择使用场景
阿波罗客户端
阿波罗客户端
・客户端的GraphQL库
・由旧Facebook开发的Relay和两个巨头
・尽管是后起之秀,但功能丰富且用户众多,与Relay相比限制较弱
阿波羅客戶端-狀態管理
希望可以横跨组件利用的状态被称为全局状态,并且其管理方法被称为”状态管理”。
在状态管理中处理的数据类型可以大致分为两种:
– 通过API传递的数据
– 其他数据(如显示共用模态框等)
阿波罗客户端 – 状态管理
使用Redux等工具来管理跨组件使用的全局状态已经成为理论化的方式。
我感到有以下的问题:
– 有很多样板代码,很麻烦。
– 如果代码量增加,需要技术人员。
Apollo Client 是一个用于状态管理的工具。
随着 SWR 和 useQuery 这样的带有缓存机制的库的流行。
具有通过API进行数据访问、通过其他方式进行数据访问的功能,可以根据识别符进行内存缓存。
Apollo客户端 – 状态管理
阿波罗还具有缓存机制,并且具备将每个对象规范化的功能。
// __typename x idを識別子としてユニーク性を担保
{ __typename: 'Post', id: 'uuid-1', name: 'something' },
{ __typename: 'Post', id: 'uuid-2', name: 'anything' }
阿波罗客户端-状态管理
可以实现以下行为:
– 通过数据变化来更新文章
– 更新文章列表的缓存
– 更新文章列表的显示
当通过API更新数据时,不再需要更新全局状态。?
Apollo Client – 状态管理
除此之外的数据,我们可以使用“响应式变量”这个功能,像以前一样手动进行更改。
Apollo Client – 状态管理
// store.js
const flagVar = makeVar(false);
// component.jsx
const Component = () => {
const flag = useReactiveVar(flagVar); // reactiveに変更を検知
return <div onClick={() => flagVar(true)}>{flag}</div>;
}
GraphQL代码生成器
GraphQL 代码生成器
能够自动生成以下内容的工具:
– API响应类型
– 数据获取的钩子
GraphQL 代码生成器
在这种情况下,自动生成的代码参考了以下内容:
·模式
·操作代码(来自客户端的请求)
GraphQL Code Generator – query(查询)
架构
// ルート型
type Query {
post: Post // フィールド(RESTのendpointに相当)
}
// オブジェクト型
type Post { id: String! title: String }
GraphQL 代码生成器 – 查询(参考)
操作码 (CaoZuoMa)
query PostPage { // オペレーションタイプ オペレーションネーム
post { // フィールド
id
title
}
}
GraphQL代码生成器 – 查询(参考)
生成的代码(节选)
type PostPageQuery = { // レスポンス型
__typename: 'Post';
id: string;
title: string | null | undefined;
};
const usePostPageQuery = useQuery(...); // hooks
GraphQL 代码生成器 – 查询(参照)
挂钩的使用方法
const Component = () => {
const { data, loading, error } = usePostPageQuery();
if (error) return throw error; // エラー
if (loading) return <div>Loading</div>; // ローディング中
return <div>{`${data.post.id}: ${data.post?.title}`}</div>;
};
GraphQL 代码生成器 – mutation(更新)
架构
type Mutation {
update_post(input: UpdatePostInput!): UpdatePostMutation!
}
type UpdatePostInput { id: String! title: String! } // パラメータ
type UpdatePostMutation { post: Post } // レスポンス
GraphQL代码生成器 – mutation(更新)
操作码
mutation PostPageUpdate($input: UpdatePostInput!) {
update_post(input: $input) {
id // ここからレスポンス
title
}
}
GraphQL代码生成器 – mutation(更新)
生成的代码(摘录)
type PostPageUpdateMutation = { // レスポンス型
__typename: 'PostPageUpdateMutation';
post: Post;
};
const usePostPageUpdateMutatiion = useMutation(...); // hooks
GraphQL 代码生成器 – mutation(更新)
钩子的用法
const Component = () => {
const [mutate] = usePostPageUpdateMutatiion(); // 関数取得
const handleUpdate = async () => {
const { error } = await mutate();
if (error) return throw error; // エラー
};
return <button onClick={handleUpdate}></button>;
};
开发的过程
开发流程
GraphQL的开发方法主要有两种:
・Code First
通过定义类型和解析器生成模式(我们采用这种方法)
・Schema First
通过模式生成代码(如gqlgen)
开发的过程
[BE] 表格设计
[ALL] 根据ER图和设计来讨论模式
[BE] 编写资源类型和解析器(逻辑)代码
[BE] 自动生成模式
[FE] 编写操作代码
[FE] 自动生成响应类型和hooks
开发流程 – 难题
这个团队分为BE(后端工程师)和FE(前端工程师),由于采用了代码优先的方式,经常会错过讨论数据库设计的时机。
一旦完成了设计和ER图,就可以在这个时间点上讨论数据库设计,这样可以顺利地推进实施工作。
最后
我在Kibela上创建了文档 ?
里面记录了常用术语和库的API,请在困难时参阅。
・GraphQL术语集合
・[前端] 如何使用ApolloClient