Cleaning Unwanted Fields From GraphQL Responses

后端 未结 3 1482
梦如初夏
梦如初夏 2020-12-09 04:49

I have an object that my GraphQL client requests.

It\'s a reasonably simple object:

type Element {
    content: [ElementContent]
    elementId: Strin         


        
相关标签:
3条回答
  • 2020-12-09 04:58

    If you want to wipe up __typename from GraphQL response (from the root and its children), you can use graphql-anywhere package.

    Something like: const wipedData = filter(inputFragment, rcvData);

    • inputFragment is a fragment defines the fields (You can see details here)
    • rcvData is the received data from GraphQL query

    By using the filter function, the wipedData includes only required fields you need to pass as mutation input.

    0 讨论(0)
  • 2020-12-09 05:09

    There are three ways of doing this

    First way

    Update the client parameter like this it will omit the unwanted fields in graphql.

    apollo.create({
      link: http,
      cache: new InMemoryCache({
        addTypename: false
      })
    });

    Second Way

    By using the omit-deep package and use it as a middleware

    const cleanTypeName = new ApolloLink((operation, forward) => {
      if (operation.variables) {
    
        operation.variables = omitDeep(operation.variables,'__typename')
      }
      return forward(operation).map((data) => {
        return data;
      });
    });
    

    Third Way

    Creating a custom middleware and inject in the apollo

    const cleanTypeName = new ApolloLink((operation, forward) => {
      if (operation.variables) {
        const omitTypename = (key, value) => (key === '__typename' ? undefined : value);
        operation.variables = JSON.parse(JSON.stringify(operation.variables), omitTypename);
      }
      return forward(operation).map((data) => {
        return data;
      });
    });
    

    and inject the middleware

    const httpLinkWithErrorHandling = ApolloLink.from([
      cleanTypeName,
      retry,
      error,
      http,
    ]);
    

    Preferred method is Third Way Because it does not have any third pary dependency and no cache performance issues

    0 讨论(0)
  • 2020-12-09 05:16

    Here's what I did, to support file uploads as well. It's a merge of multiple suggestions I found on the Github thread here: Feature idea: Automatically remove __typename from mutations

    import { parse, stringify } from 'flatted';
    
    const cleanTypename = new ApolloLink((operation, forward) => {
        const omitTypename = (key, value) => (key === '__typename' ? undefined : value);
    
        if ((operation.variables && !operation.getContext().hasUpload)) {
            operation.variables = parse(stringify(operation.variables), omitTypename);
        }
    
        return forward(operation);
    });
    

    Hooking up the rest of my client.tsx file, simplified:

    import { InMemoryCache } from 'apollo-cache-inmemory';
    import { createUploadLink } from 'apollo-upload-client';
    import { ApolloClient } from 'apollo-client';
    import { setContext } from 'apollo-link-context';
    import { ApolloLink } from 'apollo-link';
    
    const authLink = setContext((_, { headers }) => {
        const token = localStorage.getItem(AUTH_TOKEN);
        return {
            headers: {
            ...headers,
            authorization: token ? `Bearer ${ token }` : '',
            },
        };
    });
    
    
    
    const httpLink = ApolloLink.from([
        cleanTypename,
        authLink.concat(upLoadLink),
    ]);
    
    const client = new ApolloClient({
        link: httpLink,
        cache,
    });
    
    export default client;
    

    Now when I call mutations that are of type upload, I simply set the context hasUpload to true, as shown here:

    UpdateStation({variables: { input: station }, context: {hasUpload: true }}).then()
    
    0 讨论(0)
提交回复
热议问题