ra-data-graphql-simple
    TypeScript icon, indicating that this package has built-in type declarations

    3.19.0 • Public • Published

    ra-data-graphql-simple

    A GraphQL data provider for react-admin built with Apollo and tailored to target a simple GraphQL implementation.

    This is an example implementation to show how to build a graphql adapter using ra-data-graphql.

    Installation

    Install with:

    npm install --save graphql ra-data-graphql-simple

    or

    yarn add graphql ra-data-graphql-simple

    Usage

    The ra-data-graphql-simple package exposes a single function, which is a constructor for a dataProvider based on a GraphQL endpoint. When executed, this function calls the GraphQL endpoint, running an introspection query. It uses the result of this query (the GraphQL schema) to automatically configure the dataProvider accordingly.

    // in App.js
    import React from 'react';
    import { Component } from 'react';
    import buildGraphQLProvider from 'ra-data-graphql-simple';
    import { Admin, Resource } from 'react-admin';
    
    import { PostCreate, PostEdit, PostList } from './posts';
    
    const App = () => {
    
        const [dataProvider, setDataProvider] = React.useState(null);
        React.useEffect(() => {
            buildGraphQLProvider({ clientOptions: { uri: 'http://localhost:4000' } })
                .then(graphQlDataProvider => setDataProvider(() => graphQlDataProvider));
        }, []);
    
        if (!dataProvider) {
            return <div>Loading < /div>;
        }
    
        return (
            <Admin dataProvider= { dataProvider } >
                <Resource name="Post" list = { PostList } edit = { PostEdit } create = { PostCreate } />
            </Admin>
        );
    }
    
    export default App;

    Note: the parser will generate additional .id properties for relation based types. These properties should be used as sources for reference based fields and inputs like ReferenceField: <ReferenceField label="Author Name" source="author.id" reference="User">.

    Expected GraphQL Schema

    The ra-data-graphql-simple function works against GraphQL servers that respect a certain GraphQL grammar. For instance, to handle all the actions on a Post resource, the GraphQL endpoint should support the following schema:

    type Query {
      Post(id: ID!): Post
      allPosts(page: Int, perPage: Int, sortField: String, sortOrder: String, filter: PostFilter): [Post]
      _allPostsMeta(page: Int, perPage: Int, sortField: String, sortOrder: String, filter: PostFilter): ListMetadata
    }
    
    type Mutation {
      createPost(
        title: String!
        views: Int!
        user_id: ID!
      ): Post
      updatePost(
        id: ID!
        title: String!
        views: Int!
        user_id: ID!
      ): Post
      deletePost(id: ID!): Post
    }
    
    type Post {
        id: ID!
        title: String!
        views: Int!
        user_id: ID!
        User: User
        Comments: [Comment]
    }
    
    input PostFilter {
        q: String
        id: ID
        title: String
        views: Int
        views_lt: Int
        views_lte: Int
        views_gt: Int
        views_gte: Int
        user_id: ID
    }
    
    type ListMetadata {
        count: Int!
    }
    
    scalar Date

    This is the grammar used e.g. by marmelab/json-graphql-server, a client-side GraphQL server used for test purposes.

    Options

    Customize the Apollo client

    You can either supply the client options by calling buildGraphQLProvider like this:

    buildGraphQLProvider({ clientOptions: { uri: 'http://localhost:4000', ...otherApolloOptions } });

    Or supply your client directly with:

    buildGraphQLProvider({ client: myClient });

    Overriding a specific query

    The default behavior might not be optimized especially when dealing with references. You can override a specific query by wrapping the buildQuery function:

    // in src/dataProvider.js
    import buildGraphQLProvider, { buildQuery } from 'ra-data-graphql-simple';
    
    const myBuildQuery = introspection => (fetchType, resource, params) => {
        const builtQuery = buildQuery(introspection)(fetchType, resource, params);
    
        if (resource === 'Command' && fetchType === 'GET_ONE') {
            return {
                // Use the default query variables and parseResponse
                ...builtQuery,
                // Override the query
                query: gql`
                    query Command($id: ID!) {
                        data: Command(id: $id) {
                            id
                            reference
                            customer {
                                id
                                firstName
                                lastName
                            }
                        }
                    }`,
            };
        }
    
        return builtQuery;
    };
    
    export default buildGraphQLProvider({ buildQuery: myBuildQuery })

    Customize the introspection

    These are the default options for introspection:

    const introspectionOptions = {
        include: [], // Either an array of types to include or a function which will be called for every type discovered through introspection
        exclude: [], // Either an array of types to exclude or a function which will be called for every type discovered through introspection
    };
    
    // Including types
    const introspectionOptions = {
        include: ['Post', 'Comment'],
    };
    
    // Excluding types
    const introspectionOptions = {
        exclude: ['CommandItem'],
    };
    
    // Including types with a function
    const introspectionOptions = {
        include: type => ['Post', 'Comment'].includes(type.name),
    };
    
    // Including types with a function
    const introspectionOptions = {
        exclude: type => !['Post', 'Comment'].includes(type.name),
    };

    Note: exclude and include are mutually exclusives and include will take precedence.

    Note: When using functions, the type argument will be a type returned by the introspection query. Refer to the introspection documentation for more information.

    Pass the introspection options to the buildApolloProvider function:

    buildApolloProvider({ introspection: introspectionOptions });

    DELETE_MANY and UPDATE_MANY Optimizations

    You GraphQL backend may not allow multiple deletions or updates in a single query. This provider simply makes multiple requests to handle those. This is obviously not ideal but can be alleviated by supplying your own ApolloClient which could use the apollo-link-batch-http link if your GraphQL backend support query batching.

    Contributing

    Run the tests with this command:

    make test

    Install

    npm i ra-data-graphql-simple

    DownloadsWeekly Downloads

    2,262

    Version

    3.19.0

    License

    MIT

    Unpacked Size

    138 kB

    Total Files

    66

    Last publish

    Collaborators

    • fzaninotto
    • djhi