Remove Typename Link
Automatically remove __typename fields from variables.
Overview
The removeTypenameFromVariables
link automatically removes __typename
fields from variables in operations. This is useful when reusing data from a query as an argument to another GraphQL operation.
import { removeTypenameFromVariables } from '@apollo/client/link/remove-typename';const removeTypenameLink = removeTypenameFromVariables();
As an example, let's take the following query. Apollo Client will automatically add __typename
fields to the query for each field selection set.
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"// }// }
Now let's update this dashboard by sending a mutation to our server. We'll use the dashboard
as input to our mutation.
const mutation = gql`mutation UpdateDashboardMutation($dashboard: DashboardInput!) {updateDashboard(dashboard: $dashboard) {idname}}`;await client.mutate({mutation,variables: {dashboard: { ...data.dashboard, name: 'My Updated Dashboard' }}});
Without the use of the removeTypenameFromVariables
link, the server will return an error because data.dashboard
still contains the __typename
field.
Keep __typename
in JSON scalars
While the GraphQL spec disallows input fields that begin with the characters "__" (two underscores), this restriction is not applied when the input field is a JSON scalar (i.e. a scalar type that accepts raw JSON as input). When your server relies on __typename
within certain JSON
scalars, you can configure the removeTypenameFromVariables
link to retain __typename
.
Note: the JSON scalar type does not need to be literally named JSON
to be considered a JSON scalar.
Provide an except
option to map all variable types that should maintain __typename
. This is done using the KEEP
sentinel. Each key in the except
option should correspond to an input type in your GraphQL schema.
Here we tell the removeTypenameFromVariables
link to keep all __typename
fields for any variable that is declared as a JSON
type. Variable types are inferred from the GraphQL query. Let's take the following GraphQL mutation:
mutation ConfigureDashboardMutation($dashboardConfig: JSON) {configureDashboard(config: $dashboardConfig) {id}}
import { removeTypenameFromVariables, KEEP } from '@apollo/client/link/remove-typename';const removeTypenameLink = removeTypenameFromVariables({except: {JSON: KEEP}});
Here we've declared a dashboardConfig
variable as type JSON
. When the query moves through the removeTypenameFromVariables
link, the dashboardConfig
variable will be detected as a JSON
scalar type and all __typename
fields are kept intact.
Nested JSON scalar fields in input variables
Not all top-level variables may map to a JSON scalar type. For more complex input object types, the JSON scalar may be found on a nested field. The except
option allows you to configured nested fields within these types to keep __typename
intact for these fields.
import { removeTypenameFromVariables, KEEP } from '@apollo/client/link/remove-typename';const removeTypenameLink = removeTypenameFromVariables({except: {DashboardInput: {config: KEEP}}});
Variables declared as type DashboardInput
will have any top-level __typename
fields removed, but keep __typename
for the config
field.
This nesting can be as deep as needed and include as many fields as necessary. Use the KEEP
sentinel to determine where __typename
should be kept.
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}}},}});
To keep __typename
for nested fields in arrays, use the same object notation as if the field were an object type.
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}}}});
Options
Name / Type | Description |
---|---|
| Determines which input types should retain |