移除Typename Link
自动从变量中删除 __typename 字段。
概述
当将来自一个查询作为参数传递给另一个GraphQL操作时,__typename
字段可能导致错误。为了避免这种情况,您可以使用removeTypenameFromVariables
链接来自动从操作中的__typename
字段中删除变量。
从所有变量中删除__typename
例如,考虑以下查询。 Apollo Client自动为每个字段__typename
选择集添加字段。
const query = gql`query DashboardQuery($id: ID!) {dashboard(id: $id) {idname}}`;const { data } = await client.query({ query, variables: { id: 1 }});// {// "dashboard": {// "__typename": "Dashboard",// "id": 1,// "name": "My Dashboard"// }// }
现在,让我们通过向我们的服务器发送一个突变来更新这个仪表板。我们将使用之前查询返回的dashboard
作为传入突变的数据。
const mutation = gql`mutation UpdateDashboardMutation($dashboard: DashboardInput!) {updateDashboard(dashboard: $dashboard) {idname}}`;await client.mutate({mutation,variables: {dashboard: { ...data.dashboard, name: 'My Updated Dashboard' }}});
如果没有使用removeTypenameFromVariables
链接,由于data.dashboard
仍然包含__typename
字段,服务器将返回错误。
用法
您可以如此导入和实例化它
import { removeTypenameFromVariables } from '@apollo/client/link/remove-typename';const removeTypenameLink = removeTypenameFromVariables();
在您的链路链接之前引入终止链接的任何位置使用removeTypeNameLink
来从所有操作中移除变量中的__typename
字段。
import { from } from '@apollo/client';const link = from([removeTypenameLink, httpLink]);const client = new ApolloClient({link,// ... other options});
如果您使用方向性组合,例如,将订阅发送到websocket连接,请将订阅放置在splitLink
之前,以从所有操作中移除变量中的__typename
。
import { from, split } from '@apollo/client';import { removeTypenameFromVariables } from '@apollo/client/link/remove-typename';const removeTypenameLink = removeTypenameFromVariables();const splitLink = split(({ query }) => {const definition = getMainDefinition(query);return (definition.kind === 'OperationDefinition' &&definition.operation === 'subscription');},wsLink,httpLink,);const link = from([removeTypenameLink, splitLink]);const client = new ApolloClient({link,// ... other options});
在JSON标量中保留`__typename`
有时,您可能需要保留查询响应中的__typename
字段,例如在JSON标量输入字段中的__typename
。
尽管GraphQL 类型验证规范不允许使用两个下划线 开头的输入字段__
,但当输入字段是JSON 标量时,此限制不适用。
为此,在实例化removeTypenameFromVariables
时提供except
选项,并使用KEEP
哨兵表示哪些变量类型应保留__typename
。每个except
选项中的键都应与您的GraphQL模式中的输入类型对应。
例如,假设您的模式包含一个ConfigureDashboardMutation
突变,它接受一个名为$dashboardConfig
的JSON
类型变量。
mutation ConfigureDashboardMutation($dashboardConfig: JSON) {configureDashboard(config: $dashboardConfig) {id}}
您可以让removeTypenameFromVariables
链接保留任何声明为JSON
类型的变量中的所有__typename
字段。变量类型由GraphQL查询推断。
import { removeTypenameFromVariables, KEEP } from '@apollo/client/link/remove-typename';const removeTypenameLink = removeTypenameFromVariables({except: {JSON: KEEP}});
注意:JSON 标量类型不需要字面量命名为JSON
才被认为是JSON 标量。
当查询通过removeTypenameFromVariables
链接时,dashboardConfig
变量将被检测为JSON
标量类型,并且所有__typename
字段都保持不变。
输入变量中的嵌套JSON标量字段
并非所有顶层 变量都可能映射到JSON 标量类型。对于更复杂的输入对象类型,JSON标量可能位于嵌套 字段中。该except
选项可让您配置这些类型内的嵌套 字段以保持__typename
不变。
import { removeTypenameFromVariables, KEEP } from '@apollo/client/link/remove-typename';const removeTypenameLink = removeTypenameFromVariables({except: {DashboardInput: {config: KEEP}}});
变量声明的类型为DashboardInput
将移除任何顶层__typename
字段,但保持config
字段的__typename。
此嵌套可以有多深,需要多少字段就有多少字段。使用KEEP
哨兵来确定__typename
应该保留的位置。
import { removeTypenameFromVariables, KEEP } from '@apollo/client/link/remove-typename';const removeTypenameLink = removeTypenameFromVariables({except: {// Keep __typename for `bar` and `baz` fields on any variable// declared as a `FooInput` typeFooInput: {bar: KEEP,baz: KEEP,},// Keep __typename for the `baz.qux` field on any variable// declared as a `BarInput` typeBarInput: {baz: {qux: KEEP}},// Keep __typename on `bar.baz` and `bar.qux.foo` fields for any// variable declared as a `BazInput` typeBazInput: {bar: {baz: KEEP,qux: {foo: KEEP}}},}});
要在数组中的嵌套字段中保留__typename
,请使用与字段为对象类型时的相同对象表示法。
import { removeTypenameFromVariables, KEEP } from '@apollo/client/link/remove-typename';const removeTypenameLink = removeTypenameFromVariables({except: {// Keep __typename on the `config` field for each widget// in the `widgets` array for variables declared as// a `DashboardInput` typeDashboardInput: {widgets: {config: KEEP}}}});
选项
名称 类型 | 描述 |
---|---|
| 确定哪些输入类型应该保留 |