Intercepting GraphQL operations
在 Web 上,GraphQL API 通常通过 HTTP 实现。这意味着,从技术上讲,你仍然可以使用 http
命名空间像拦截常规 HTTP 请求一样拦截 GraphQL 操作。但是,建议使用指定的 graphql
命名空间,因为它在使用 GraphQL 时可以提供更好的开发者体验和更丰富的功能集。
¥On the web, GraphQL APIs are often implemented over HTTP. This means that, technically, you can still use the http
namespace to intercept your GraphQL operations as regular HTTP requests. However, it is recommended to use the designated graphql
namespace instead, as it provides a better developer experience and a richer feature-set when it comes to working with GraphQL.
本页将引导你了解使用 MSW 拦截 GraphQL 操作的所有可能方法。
¥This page will walk you through the possible ways to intercept a GraphQL operation with MSW.
端点优先模拟
¥Endpoint-first mocking
默认情况下,该库在匹配 GraphQL 操作时会忽略服务器发送点。这是一个经过深思熟虑的决定,因为单个应用很少会与多个 GraphQL API 交互。这意味着即使一个 GetUser
操作发送给 /api/graphql
,另一个发送给 https://api.example.com
,同一个处理程序也会匹配该操作。
¥By default, the library ignores the server sendpoint when matching GraphQL operations. That is a conscious decision since it is rare that a single application would interact with multiple GraphQL APIs. It means that the same handler will match a GetUser
operation even if one is sent to /api/graphql
and the other to https://api.example.com
.
此默认值支持向后兼容,但强烈建议使用 graphql.link()
将 GraphQL 模拟范围限定在特定的服务器端点。
¥This default is supported for backward-compatibility, but it is strongly recommended to use graphql.link()
to scope GraphQL mocking to a particular server endpoint.
import { graphql } from 'msw'
const github = graphql.link('https://api.github.com/graphql')
const stripe = graphql.link('https://api.stripe.com/graphql')
export const handlers = [
github.query('GetUser', oneResolver),
stripe.query('GetUser', anotherResolver),
]
通过定义 GraphQL 链接,你可以告诉 MSW 在执行操作匹配时考虑服务器端点。
¥By defining GraphQL links, you tell MSW to take the server endpoint into account when performing operation matching.
操作类型
¥Operation kind
该库支持拦截 GraphQL 查询和变更(订阅支持即将推出)。了解有关拦截所需操作类型的更多信息:
¥The library supports intercepting GraphQL queries and mutations (subscriptions support coming soon). Learn more about intercepting the operation kind you need:
你还可以拦截任何 GraphQL 操作,无论其类型如何,这在模棱两可的上下文中非常方便。在此页面上了解有关该方法的更多信息:
¥You can also intercept any GraphQL operation regardless of its kind, which is handy in ambiguous contexts. Learn more about that approach on this page:
Operations
Learn about interceping any GraphQL operation
谓词
¥Predicate
命名操作
¥Named operations
使用该库时,使用命名的 GraphQL 操作并非必需,但强烈建议你这样做。由于 MSW 中的 GraphQL 模拟默认是基于操作而非基于字段的,因此命名操作将更容易拦截。
¥It is not required but strongly recommended to use named GraphQL operations when working with the library. Named operations will allow for easier interception since GraphQL mocking in MSW is operation-based and not field-based by default.
# The following GraphQL query can be handled
# with a handler that looks like this:
#
# graphql.query('GetUser', resolver)
query GetUser {
user {
id
}
}
你可以按照 Schema 优先模拟 方案选择使用基于字段的模拟。也可以将两者结合起来!
¥You can opt to use field-based mocking by following the Schema-first mocking recipe. Combining the two is also an option!
操作名称
¥Operation name
你可以提供一个字符串作为请求处理程序谓词,该谓词表示你希望拦截的 GraphQL 操作的名称。
¥You can provide a string as a request handler predicate that represents the name of the GraphQL operation you wish to intercept.
graphql.query('GetUser', () => {})
此处理程序将匹配以下 GraphQL 查询:
¥This handler will match the following GraphQL query:
query GetUser { user { ... } }
变更也是如此,但不要忘记使用 graphql.mutation()
。
¥The same is true for mutations, just don’t forget to use graphql.mutation()
instead.
正则表达式
¥Regular expression
你可以提供正则表达式作为请求处理程序谓词。MSW 将根据该表达式测试传出的操作名称,以确定它们是否匹配。
¥You can provide a regular expression as a request handler predicate. MSW will test the outgoing operation names against that expression to determine if they match.
graphql.mutation(/user/i, () => {})
此处理程序将匹配
CreateUser
和UpdateUser
突变。¥This handler will match both
CreateUser
andUpdateUser
mutations.
响应解析器
¥Response resolver
响应解析器对象参数中为 graphql.*
处理程序提供了以下属性:
¥The following properties are available on the response resolver object argument for graphql.*
handlers:
属性 | 类型 | 描述 |
---|---|---|
cookies | Record<string, string> | 已解析请求的 cookie。 |
query | string | 原始 GraphQL 查询字符串。 |
variables | Record<string, any> | 已解析此操作的 variables。 |
operationName | string | 操作名称(例如 'GetUser' )。 |
graphql.mutation(
'UpdateUser',
({ cookies, query, variables, operationName }) => {},
)
后续步骤
¥Next steps
现在你已经了解了如何拦截 GraphQL 操作,接下来学习如何处理它们的响应:
¥Now that you know how to intercept GraphQL operations, proceed by learning how to handle their responses:
Mocking responses
Different ways to handle an intercepted GraphQL operation.