Does apollo-client work on node.js?

前端 未结 7 1537
醉酒成梦
醉酒成梦 2020-12-16 09:34

I need a graphql client lib to run on node.js for some testing and some data mashup - not in a production capacity. I\'m using apollo everywhere else (

7条回答
  •  佛祖请我去吃肉
    2020-12-16 10:17

    I was running into your same question, because I wanted to create a middleware service to prepare data from graphQL to a final frontend application, to have :

    • optimised data representation (and standard output data interface)
    • faster response time

    assuming that graphQL server is provided by an external provider , so no ownership to data model, directly with GQL

    So I didn't want to implement GraphQL Apolloclient directly in a frontend framework like React / Angular, Vuejs... but manage the queries via Nodejs at backend of a REST API.

    So this is the class wrapper for Apolloclient I was able to assemble (using typescript):

    import ApolloClient from "apollo-client";
    import { ApolloLink } from 'apollo-link'
    import { HttpLink } from 'apollo-link-http'
    import { onError } from 'apollo-link-error'
    import fetch from 'node-fetch'
    import { InMemoryCache, IntrospectionFragmentMatcher } from 'apollo-cache-inmemory'
    import introspectionQueryResultData from '../../fragmentTypes.json';
    import { AppConfig } from 'app-config';
    
    
    const config: AppConfig = require('../../../appConfig.js');
    
    export class GraphQLQueryClient {
        protected apolloClient: any;
    
        constructor(headers: { [name: string]: string }) {
            const api: any = {
                spaceId: config.app.spaceId,
                environmentId: config.app.environmentId,
                uri: config.app.uri,
                cdnApiPreviewToken: config.cdnApiPreviewToken,
            };
            // console.log(JSON.stringify(api));
            const ACCESS_TOKEN = api.cdnApiPreviewToken;
            const uri = api.uri;
    
            console.log(`Apollo client setup to query uri: ${uri}`);
    
            const fragmentMatcher = new IntrospectionFragmentMatcher({
                introspectionQueryResultData
            });
    
            this.apolloClient = new ApolloClient({
                link: ApolloLink.from([
                    onError(({ graphQLErrors, networkError }:any) => {
                        if (graphQLErrors) {
                            graphQLErrors.map((el:any) =>
                                console.warn(
                                    el.message || el
                                )
                            )
                            graphQLErrors.map(({ message, locations, path }:any) =>
                                console.warn(
                                    `[GraphQL error - Env ${api.environmentId}]: Message: ${message}, Location: ${JSON.stringify(locations)}, Path: ${path}`
                                )
                            )
                        }
                        if (networkError) console.log(`[Network error]: ${networkError}`)
                    }),
                    new HttpLink({
                        uri,
                        credentials: 'same-origin',
                        headers: {
                            Authorization: `Bearer ${ACCESS_TOKEN}`
                        },
                        fetch
                    })
                ]),
                cache: new InMemoryCache({ fragmentMatcher }),
                // fetchPolicy as network-only avoids using the cache.
                defaultOptions: {
                    watchQuery: {
                        fetchPolicy: 'network-only',
                        errorPolicy: 'ignore',
                    },
                    query: {
                        fetchPolicy: 'network-only',
                        errorPolicy: 'all',
                    },
                }
            });
        }
    }   
    

    After this constructor I run queries like :

    let response = await this.apolloClient.query({ query: gql`${query}` });
    

    As you might have noticed:

    • I needed to inject fetch on Httplink

    • I had to setup Authorization headers to access external provider graphQL endpoint

    • I used IntrospectionFragmentMatcher in order to use Fragments in my queries, along with building schema type ("fragmentTypes.json" with an init script)

    Posting this to just add my experience and maybe more info for the question. Also looking forward for comments and points of improvement for this wrapper.

提交回复
热议问题