Coder Social home page Coder Social logo

Comments (12)

shalzz avatar shalzz commented on May 2, 2024 1

@annared @djhi I am just using my own apollo graphql server backend and this worked pretty well with it. I think the aor-graphql-client can handled most of the common variations of a graphql server but yes better documentation, especially about the operationNames interospection options would definitely help others

One thing that would be great to have maybe at the admin-on-rest core level would be the ability to map parameters like id to something else used as a primary key. Of course right now I'm just adding the id at the response parsing of each response..

The only trouble I've had is that after an update the app data isn't updated until a complete page refresh and I have yet to find the cause of the problem. Saw #34

from aor-graphql.

shalzz avatar shalzz commented on May 2, 2024 1

I don't have it in a public repo but this is basically my queryBuilder:

const queryBuilder = introspectionResults => (aorFetchType, resourceName, params) => {
    const resource = introspectionResults.resources.find(r => r.type.name === resourceName);
    const fields = buildFieldList(aorFetchType, resource, introspectionResults);

    return {
        query: buildQueries(aorFetchType, resource, fields, resourceName),
        variables: buildVariables(aorFetchType, params),
        parseResponse: response => buildResponseParsers(aorFetchType, response, resource),
    }
}

const buildQueries = (aorFetchType, resource, fields, resourceName) => {
    switch (aorFetchType) {
        case 'GET_LIST':
        case 'GET_MANY':
        case 'GET_MANY_REFERENCE':
            return gql`query ${resource[aorFetchType].name}($page: Int, $perPage: Int, $sortField: String, $sortOrder: String, $filter: String) {
                    ${resource[aorFetchType].name}(page: $page, perPage: $perPage, sortField: $sortField, sortOrder: $sortOrder, filter: $filter) {
                        items { ${fields} }
                        totalCount
                    }
                }`
        case 'GET_ONE':
            return gql`query ${resource[aorFetchType].name}($id: ID!) {
                    data: ${resource[aorFetchType].name}(sku: $id) {
                        ${fields}
                    }
                }`
        case 'CREATE':
        case 'UPDATE':
            return gql`mutation ${resource[aorFetchType].name}($data: ProductInput!) {
                    ${resource[aorFetchType].name}(${resourceName.toLowerCase()}: $data) {
                        ${fields}
                    }
                }`
        case 'DELETE':
            return gql`mutation ${resource[aorFetchType].name}($id: ID!) {
                    data: ${resource[aorFetchType].name}(sku: $id) 
                }`
        default:
            return undefined;
    }
}

const buildVariables = (aorFetchType, params) => {
    switch (aorFetchType) {
        case 'GET_LIST':
        case 'GET_MANY':
        case 'GET_MANY_REFERENCE':
            return {
                page: params.pagination.page,
                perPage: params.pagination.perPage,
                sortField: params.sort.field,
                sortOrder: params.sort.order,
                filter: JSON.stringify(params.filter)
            }
        case 'GET_ONE':
        case 'DELETE':
            return params;
        case 'CREATE':
        case 'UPDATE':
            let data = JSON.parse(JSON.stringify(params.data));
            sanitize(data);
            return {data: data};
        default:
            return undefined;
    }
}

const buildResponseParsers = (aorFetchType, response, resource) => {
    let data;
    switch (aorFetchType) {
        case 'GET_LIST':
        case 'GET_MANY':
        case 'GET_MANY_REFERENCE':
            data = response.data[resource[aorFetchType].name];
            const items = data.items.map(item => {
                return {
                    ...item,
                    id: item.sku
                }
            })
            return { data: items, total: data.totalCount }
        case 'GET_ONE':
        case 'DELETE':
            data = response.data.data;
            const new_data = {
                ...data,
                id: data.sku
            };
            return { data: new_data };
        case 'CREATE':
        case 'UPDATE':
            data = response.data[resource[aorFetchType].name]
            data.id = data.sku;
            return { data: data };
        default:
            return undefined;
    }
}

const sanitize = (obj) => {
    delete obj.id;
    delete obj.__typename;
    Object.keys(obj).map(child => {
        if (typeof obj[child] === 'object')
            return sanitize(obj[child])
        return obj[child];
    })
}

export default () => buildApolloClient({
    query: { fetchPolicy: 'network-only' },
    client: apolloClient,
    introspection: introspectionOptions,
    queryBuilder: queryBuilder
});

from aor-graphql.

djhi avatar djhi commented on May 2, 2024 1

It might be useful that the aor-graphql-client package provide some basic query building functions from introspection, such as the buildFieldList. They are currently all inside the aor-graphql-client-graphcool package because I was not sure about which one would be reusable. I'll see if I can do that soon

from aor-graphql.

shalzz avatar shalzz commented on May 2, 2024 1

I actually got that from marmelab/aor-simple-graphql-client

from aor-graphql.

djhi avatar djhi commented on May 2, 2024

Can you share an example ?

from aor-graphql.

shalzz avatar shalzz commented on May 2, 2024
import buildApolloClient from 'aor-graphql-client';
...

class App extends Component {
    constructor() {
        super();
        this.state = { restClient: null };
    }
    componentDidMount() {
        buildApolloClient({
            client: {
                networkInterface: createNetworkInterface({
                    uri: 'http://localhost:3001/graphql',
                }),
            },
        }).then(restClient => this.setState({ restClient }));
    }

    render() {
        const { restClient } = this.state;

        if (!restClient) {
            return <div>Loading</div>;
        }

        return (
            <Admin restClient={restClient}>
            </Admin>
        );
    }
}

I am using the latest npm version of aor-graphql-client

from aor-graphql.

djhi avatar djhi commented on May 2, 2024

Oh I see, you're importing from aor-graphql-client. This package only provide the basis to integrate graphQL with admin-on-rest. And as stated in this package README, you must provide a queryBuilder option.

We currently only provided a builder for graphcool. We will work on a sample custom implementation soon. In the mean time, you'll have to look at the graphcool client code to learn how it work.

from aor-graphql.

shalzz avatar shalzz commented on May 2, 2024

Oh I somehow thought that was optional. Anyways thanks. I'll look into the graphqlcool client.

from aor-graphql.

djhi avatar djhi commented on May 2, 2024

Are you planning to use it with another backend ? If you do, can you please give us feedbacks about it ? Thx !

from aor-graphql.

annared avatar annared commented on May 2, 2024

@shalzz did you managed to make it work?

from aor-graphql.

annared avatar annared commented on May 2, 2024

@shalzz do you have your code in a repo? i'm curious to see how you implemented it.
I have a graphql server backend (i'm using express) but i was using the older version of aor-graphql-client (aor-simple-graphql-client)

from aor-graphql.

astoimenov avatar astoimenov commented on May 2, 2024

@shalzz what about buildFieldList ? where do you get this from?

from aor-graphql.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.