GraphQL 是一种用于 API 的查询语言,它使得客户端可以精确地请求需要的数据,避免了传统 RESTful API 中的 over-fetching 和 under-fetching 的问题。而 Apollo Server/Client 是一套基于 GraphQL 的全栈解决方案,它包含了一个高性能的 GraphQL 服务器和一个用于构建客户端的 GraphQL 客户端库。本文将会介绍 Apollo Server/Client 的 GraphQL 实现以及在使用过程中可能遇到的 bug,以及如何解决这些 bug。
Apollo Server
GraphQL Schema
GraphQL Schema 定义了一个 GraphQL API 的类型、字段、查询、变量等信息。在 Apollo Server 中,我们可以使用 GraphQL schema language 或者 JavaScript 来定义 GraphQL schema。下面是一个使用 GraphQL schema language 定义的简单的 schema:
type Query { hello: String } schema { query: Query }
这个 schema 定义了一个 Query 类型,它有一个名为 hello 的字段,类型为 String。同时,这个 schema 定义了一个名为 query 的 schema。
Resolvers
GraphQL Resolver 是一个函数,它负责处理一个 GraphQL 查询,并返回一个结果。在 Apollo Server 中,我们可以使用 JavaScript 编写 Resolver。下面是一个简单的 Resolver:
const resolvers = { Query: { hello: () => "Hello World!" } }
这个 Resolver 处理了一个名为 hello 的查询,并返回一个字符串 "Hello World!"。
数据源
在实际的应用中,数据通常来自于数据库、第三方 API 或者其他的数据源。在 Apollo Server 中,我们可以使用 data source 来管理这些数据源。下面是一个使用 data source 的例子:
-- -------------------- ---- ------- ----- ------- ------- ---------- - ------------- - -------- ---------- - - - --- -- ----- ------ -- - --- -- ----- ------ - -- - ---------- - ------ ----------- - --------------- - ------ -------------------- -- ------- --- ---- - - ----- ------ - --- -------------- --------- ---------- ------------ -- -- -- -------- --- --------- -- ---
这个例子中,我们创建了一个 UserAPI 的 data source,它包含了一个 users 数组,每个元素都有一个 id 和一个 name。getUserById 方法可以根据 id 查找对应的用户。
Bug 总结
1. 数据库查询出错
在使用 data source 的过程中,如果我们使用了数据库作为数据源,有时候会遇到查询出错的问题。这个问题通常是因为数据库连接池中的连接没有正确释放导致的。解决这个问题的方法是在每次查询完成后手动释放连接。
-- -------------------- ---- ------- ----- ------- ------- ---------- - ------------- - -------- --------- - ------------------ ----- ------------ ----- ------- --------- --------- --------- ------ --- - ---------- - ------ --- ----------------- ------- -- - ----------------------------- ----------- -- - -- ----- - ------ ------------ - ------------------------ - ---- ------- ----- -------- -- - --------------------- -- ----- - ------ ------------ - ----------------- --- --- --- - -
2. 数据源缓存不更新
在使用 data source 的过程中,如果我们使用了缓存,有时候会遇到缓存不更新的问题。这个问题通常是因为缓存没有正确的更新导致的。解决这个问题的方法是在每次更新数据源后手动更新缓存。
-- -------------------- ---- ------- ----- ------- ------- ---------- - ------------- - -------- ---------- - - - --- -- ----- ------ -- - --- -- ----- ------ - -- - ---------- - ------ ----------- - ------------- - ---------------------- ---------------------- ------ - - ----- ------ - --- -------------- --------- ---------- ------------ -- -- -- -------- --- --------- --- -------------- - ---------- ------------------ ---------- -- - ----- ------- - --- ---------- ----------------------- ---- -- - ------------------------------- ----- ------------- -------- ---- ---- --- ------ - ------- -- - - ---
这个例子中,我们在 addUser 方法中手动触发了一个 userAdded 事件,在 subscriptions 中监听这个事件,并手动发送一个 USER_ADDED 消息。
Apollo Client
GraphQL Query
在 Apollo Client 中,我们可以使用 GraphQL Query 来查询数据。下面是一个简单的 Query:
query GetUsers { users { id name } }
这个 Query 查询了一个名为 users 的字段,它包含了两个字段,id 和 name。
React Hooks
在 React 中,我们可以使用 Apollo Client 提供的 React Hooks 来查询数据。下面是一个使用 useQuery Hooks 的例子:
-- -------------------- ---- ------- ------ - --------- --- - ---- ----------------- ----- --------- - ---- ----- -------- - ----- - -- ---- - - -- -------- ------- - ----- - -------- ------ ---- - - -------------------- -- --------- - ------ ---------------------- - -- ------- - ------ ------------------ - ------ - ---- -------------------- -- - --- ------------------------------ --- ----- -- -
这个例子中,我们使用了 useQuery Hooks 来查询数据,并在组件中渲染了查询结果。
Mutation
在 Apollo Client 中,我们可以使用 Mutation 来修改数据。下面是一个简单的 Mutation:
mutation AddUser($input: AddUserInput!) { addUser(input: $input) { id name } }
这个 Mutation 接受一个名为 input 的变量,并返回一个包含 id 和 name 的对象。
React Hooks
在 React 中,我们可以使用 Apollo Client 提供的 React Hooks 来执行 Mutation。下面是一个使用 useMutation Hooks 的例子:
-- -------------------- ---- ------- ------ - ------------ --- - ---- ----------------- ----- -------- - ---- -------- --------------- -------------- - -------------- ------- - -- ---- - - -- -------- --------- - ----- --------- - -------- ----- -- - ---------------------- ----- ------------ - ----- -- - ----------------------- ----- ----- - - ----- ----------------------- -- --------- ---------- - ----- -- ------- ------- - ----- - ------- - -- -- - ----- - ----- - - ----------------- ------ --------- --- ------------------ ------ ---------- ----- - ------ ---------- -------- - --- - --- -- ------ - ----- ------------------------ ------ ----------- ----------- -- ------- ----------------- ------------- -------- -- ---------------------- ------ -- ------------------ ------- -- -
这个例子中,我们使用了 useMutation Hooks 来执行 Mutation,并在组件中渲染了 Mutation 的结果。
Bug 总结
1. 缓存不清理
在使用 Apollo Client 的过程中,如果我们使用了缓存,有时候会遇到缓存不清理的问题。这个问题通常是因为缓存没有正确的清理导致的。解决这个问题的方法是手动清理缓存。
-- -------------------- ---- ------- ----- --------- - --------------------- - ------- ------- - ----- - ------- - -- -- - -------------- ------- - ------------------- - --- - ----- ---------- - --------------------- ----- -------- --------- ---- -------- ------- -- ---- - -- ---- - - --- ------ ------------------ ------------ - - --- - --- ----- ------------ - -- -- - ------------ ---------- - -- -- ------- ----- -- - -------------- ------- - ------------------- - --- - --------- -- - ------ --------------------- ------- -- -- --- --------------- -------- -- - - --- - --- --
这个例子中,我们手动修改了缓存中的数据,并手动清理了缓存中的数据。
2. 多个请求并发
在使用 Apollo Client 的过程中,如果我们同时发起多个请求,有时候会遇到多个请求并发的问题。这个问题通常是因为多个请求共享同一个缓存导致的。解决这个问题的方法是为每个请求创建一个独立的缓存。
-- -------------------- ---- ------- ----- ------ - --- -------------- ------ --- --------------- ------------- - ------ - ------- - ------ - -------- ------ -------------- - --- --------- - ------ ------------- ------------- - - - - - --- ----- --- ---------- ---- ----------------------------- -- --- ----- -------- - ----- -- -- - ----- ------ - --- -------------- ------ --- ---------------- ----- --- ---------- ---- ----------------------------- -- --- ----- - ---- - - ----- -------------- ------ --------- --- ------ ----------- --
这个例子中,我们为每个请求创建一个独立的缓存,并使用这个缓存来查询数据。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/65cdb563add4f0e0ff6e3c54