Git Product home page Git Product logo

aor-simple-graphql-client's Introduction

archived Archived Repository
This code is no longer maintained. Feel free to fork it, but use it at your own risks.

aor-simple-graphql-client

Deprecated: Work on GraphQL integration has been moved to aor-graphql

Build Status

A simple GraphQL client for admin-on-rest built with Apollo

A version of the admin-on-rest demo using this client is available at https://marmelab.com/admin-on-rest-graphql-demo.
The source code for this demo is available at https://github.com/marmelab/admin-on-rest-graphql-demo.

About GraphQL and Apollo

This library is meant to be used with Apollo on the client side but you're free to use any graphql server.

Note that this client is not compatible with graphcool. However, another client exists for graphcool: aor-graph-cool-client.

Installation

Install with:

npm install --save aor-simple-graphql-client

or

yarn add aor-simple-graphql-client

Usage

Let's create a file for our admin page admin.js:

import React, { Component } from 'react';
import { buildApolloClient } from 'aor-simple-graphql-client';

import { Admin, Resource } from 'admin-on-rest';
import { Delete } from 'admin-on-rest/lib/mui';

import { PostCreate, PostEdit, PostList } from '../components/admin/posts';

const client = new ApolloClient();

class AdminPage extends Component {
    constructor() {
        super();
        this.state = { restClient: null };
    }
    componentDidMount() {
        buildApolloClient()
            .then(restClient => this.setState({ restClient }));
    }

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

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

        return (
            <Admin restClient={restClient}>
                <Resource name="Post" list={PostList} edit={PostEdit} create={PostCreate} remove={Delete} />
            </Admin>
        );
    }
}

export default AdminPage;

And that's it, buildApolloClient will create a default ApolloClient for you and run an introspection query on your graphql endpoint.

By default, it expect the following queries and mutations for each resource:

List resources with pagination

Example with resource Post:

getPageOfPosts(page: Int, perPage: Int, sortField: String, sortOrder: String, filter: String) {
    items: [Post]
    totalCount: Int
}

Note that the function should be named with the plural version of Post. We use pluralize to generate it.

filter may contain a serialized JSON object, for example:

'{ "authorId": "4e80878c-6baa-4506-a93c-ef99b74e73e0" }'

Get a resource

Example with resource Post:

getPost(id: ID!) Post

Create a new resource

Example with resource Post:

createPost(data: String) Post

data is a serialized JSON object, for example:

'{ "title": "My first post", "authorId": "4e80878c-6baa-4506-a93c-ef99b74e73e0", "body": "..." }'

Update a resource

Example with resource Post:

updatePost(data: String) Post

data is a serialized JSON object, for example:

'{ "id": "c02e92e8-2a21-4ae7-9197-cb9601861a44", "title": "My first post", "authorId": "4e80878c-6baa-4506-a93c-ef99b74e73e0", "body": "..." }'

Remove a resource

Example with resource Post:

removePost(id: ID!) Boolean

Options

Customize the Apollo client

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

buildApolloClient({ clientOptions: { uri: 'http://localhost:3000', ...otherApolloOptions } });

Or supply your client directly with:

buildApolloClient({ client: myClient });

GraphQL flavor

A flavor act as the translator between Admin-on-rest requests and your GraphQL queries and mutations.

This is useful if you want more control over which paramaters are sent from Admin-on-rest to your GraphQL backend, and how they are sent.

A flavor is an object with a key for each rest action defined by Admin-on-rest: GET_ONE, GET_LIST, GET_MANY, GET_MANY_REFERENCE, CREATE, UPDATE and DELETE.

For each of these actions, it defines:

  • how the name of the operation (query or mutation) can be inferred during introspection
  • how the query will be generated through introspection
  • how parameters are translated from Admin-on-rest to Apollo
  • how the query results from Apollo to Admin-on-rest are parsed

For example, this is the GET_LIST definition in the default flavor:

export default {
    [GET_LIST]: {
        operationName: resourceType => `getPageOf${pluralize(resourceType.name)}`,
        getParameters: params => ({
            filter: JSON.stringify(params.filter),
            page: params.pagination.page - 1,
            perPage: params.pagination.perPage,
            sortField: params.sort.field,
            sortOrder: params.sort.order,
        }),
    },
    ...
};

To define a custom GraphQL flavor, pass it in the options:

buildApolloClient({ flavor: myGraphCoolFlavor });

Customize the introspection

These are the default options for introspection:

const introspectionOptions = {
    includeTypes: null, // Either an array of types to include or a function which will be called with each OBJECT type discovered through introspection
    excludeTypes: null, // Either an array of types to exclude or a function which will be called with each OBJECT type discovered through introspection (`Query` and `Mutation` are excluded anyway)
    includeQueries: null, // Either an array of queries to include or a function which will be called with each query discovered through introspection
    excludeQueries: null, // Either an array of queries to exclude or a function which will be called with each query discovered through introspection
    includeMutations: null, // Either an array of mutations to include or a function which will be called with each mutation discovered through introspection
    excludeMutations: null, // Either an array of mutations to exclude or a function which will be called with each mutation discovered through introspection
    excludeFields: null, // Either an array of fields to exclude or a function which will be called with each field discovered through introspection on a specific object (more details below)
    ignoreSubObjects: true, // If true, introspection will ignore sub objects AND sub resources from the returned fields (more details below)
    ignoreSubResources: true, // If true and ignoreSubObjects is false, introspection will ignore sub resources from the returned fields (more details below)
}

And how you pass them to the buildApolloClient function:

buildApolloClient({ introspection: introspectionOptions });

Note: excludeXXX and includeXXX are mutualy exclusives and includeXXX will always take precendance.

excludeFields deserves more details. If supplying a function, it will receive the following parameters:

  • field: the field definition (see the documentation on introspection for more details)
  • resource: the resource type (for example: Post)
  • type: the operation type (matching those of admin-on-rest, for example: GET_LIST)

ignoreSubObjects can be set to false to include sub objects in queries and mutations results. Consider the following GQL schema:

    type Customer {
        id ID!
        name String
    }

    type Product {
        id ID!
        reference String
    }

    type OrderItem {
        productId ID!
        product Product
        quantity Int
    }

    type Order {
        id ID!
        customerId ID!
        customer Customer
        date Date
        items: [OrderItem]
    }

If ignoreSubObjects is true (the default) and ignoreSubResources is true (the default), the getOrder query will be generated like this:

    getOrder(id ID!) {
        id
        customerId
        date
    }

If ignoreSubObjects is false and ignoreSubResources is true, the getOrder query will be generated like this:

    getOrder(id ID!) {
        id
        customerId
        date
        items {
            productId
            quantity
        }
    }

If ignoreSubObjects is false and ignoreSubResources is false, the getOrder query will be generated like this:

    getOrder(id ID!) {
        id
        customerId
        customer { id name }
        date
        items {
            productId
            product { id reference }
            quantity
        }
    }

Note: Remember that those two options could lead to recursive loading of many resources. Use them with caution.

Supply your own queries and mutations

You need even more control? Then provide your queries with the following format:

const queries = {
    Post: {
        GET_LIST: () => gql`your query`, // Variables will be: { page: Int, perPage: Int, sortFilter: String, sortOrder: String, filter: String }
        GET_MANY: () => gql`your query`, // Optional, see note below. Variables will be: { filter: String }
        GET_MANY_REFERENCE: () => gql`your query`, // Optional, see note below. Variables will be: { filter: String }
        GET_ONE: () => gql`your query`, // Variables will be: { id: ID }
        CREATE: () => gql`your query`, // Variables will be: { data: String }
        UPDATE: () => gql`your query`, // Variables will be: { data: String }
        DELETE: () => gql`your query`, // Variables will be: { id: ID }
    }
}
buildApolloClient({ queries });

Note: You can mix introspection and custom queries by just supplying your custom queries. If you want to disable introspection, set the introspection option to false.

buildApolloClient({ queries, introspection: false });

Realtime updates

DICLAIMER This is currently not stable. We have only tested the Apollo polling mechanisms. We still have to investigate subscriptions.

Using ApolloClient, one is able to get real time updates when data changes: see their documentation for details.

With aor-simple-graphql-client, you can enable real time updates like this:

import React, { Component } from 'react';
import { buildApolloClient } from 'aor-simple-graphql-client';

import { Admin, Resource } from 'admin-on-rest';
import { Delete } from 'admin-on-rest/lib/mui';

import { PostCreate, PostEdit, PostList } from '../components/admin/posts';

const client = new ApolloClient();

class AdminPage extends Component {
    constructor() {
        super();
        this.state = { restClient: null };
    }
    componentDidMount() {
        buildApolloClient()
            .then(restClient => this.setState({ restClient }));
    }

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

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

        return (
            <Admin restClient={restClient} customSagas={[restClient.saga()]}>
                <Resource name="Post" list={PostList} edit={PostEdit} create={PostCreate} remove={Delete} />
            </Admin>
        );
    }
}

export default AdminPage;

We simply pass a custom saga to the Admin component.

By default, it will use the Apollo polling mechanism with a pollInterval of 2 seconds for all GET_LIST and GET_ONE requests.

Customization

You can specify the options to pass to the watchQuery function:

For all resources and request types

    const apolloWatchOptions = {
        pollInterval: 10000,
    };

    const apolloSaga = restClient.saga(apolloWatchOptions);

Or, you can supply a function instead of an object and it will be call with resource and requestType parameters:

    const apolloWatchOptions = (resource, requestType) => ({
        pollInterval: 10000,
    });

    const apolloSaga = restClient.saga(apolloWatchOptions);

For a specific resources and all request types

    const apolloWatchOptions = {
        Post: {
            pollInterval: 10000,
        },
        Comment: {
            pollInterval: 5000,
        },
    };

    const apolloSaga = restClient.saga(apolloWatchOptions);

Or, you can supply a function instead of an object and it will be call with a requestType parameter:

    const apolloWatchOptions = (resource, requestType) => {
        Post: {
            pollInterval: 10000,
        },
        Comment: {
            (requestType): => ({
                pollInterval: 5000,
            }),
        },
    };

    const apolloSaga = restClient.saga(apolloWatchOptions);

For a specific resources and request type

    const apolloWatchOptions = {
        Post: {
            pollInterval: 2000,
        },
        Comment: {
            GET_ONE: {
                pollInterval: 10000,
            },
            GET_LIST: {
                pollInterval: 5000,
            },
        },
    };

    const apolloSaga = restClient.saga(apolloWatchOptions);

Or, you can supply a function instead of an object:

    const apolloWatchOptions = (resource, requestType) => {
        Post: {
            pollInterval: 10000,
        },
        Comment: {
            GET_ONE: {
                pollInterval: 10000,
            },
            GET_LIST: {
                (): => ({
                    pollInterval: 5000,
                }),
            },
        },
    };

    const apolloSaga = restClient.saga(apolloWatchOptions);

Contributing

Run the tests with this command:

make test

Coverage data is available in ./coverage after executing make test.

An HTML report is generated in ./coverage/lcov-report/index.html.

aor-simple-graphql-client's People

Contributors

alexisjanvier avatar dervos avatar djhi avatar fzaninotto avatar grahamlyus avatar pancho111203 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

aor-simple-graphql-client's Issues

[RFC] Complete rewrite and deprecation

Hi all,

This project was a POC to explore how to use GraphQL with Admin-on-rest.

We're currently working on a more robust client with an easier and cleaner way to customize for backends such as graphcool. We'll release a graphcool client based on it soon after.

This is the proposed API:

aor-graphql-client

Will be responsible for making calls to the backend and retrieving the introspection results.

It'll expose an AOR client factory function taking the following options:

{
    client: {} // Either a custom Apollo client or options to create one
    queryBuilder: (introspectionResults, options) => () => {} // A function which will be called with the introspection results and must return an aor client compatible function (more on that later)
    introspection: { // An object defining the names for the queries and mutations to look for, or false to disable
        GET_LIST: (resource) => `all${pluralize(resource.type.name)}`,
        GET_ONE: (resource) => `${resource.type.name}`,
        CREATE: (resource) => `create${resource.type.name}`,
        UPDATE: (resource) => `update${resource.type.name}`,
        DELETE: (resource) => `remove${resource.type.name}`,
    }
}

The supplied queryBuilder will be called once with the introspection results and the options passed to the client.

The introspection results will take the following form:

{
    resources: [{
        type: Object, // GQL type for this resources
        GET_LIST: Object, // GQL type for the query matching the GET_LIST verb (depends on the name defined in introspection templates)
        GET_ONE: Object, // GQL type for the query matching the GET_ONE verb (depends on the name defined in introspection templates)
        CREATE: Object, // GQL type for the query matching the CREATE verb (depends on the name defined in introspection templates)
        UPDATE: Object, // GQL type for the query matching the UPDATE verb (depends on the name defined in introspection templates)
        DELETE: Object, // GQL type for the query matching the DELETE verb (depends on the name defined in introspection templates)
    }],
    queries: [], // All queries and mutations found through introspection
    types: [], // All types found through introspection
}

It must return a function which follow the standard admin-on-rest client signature and return an object containing the apollo query methods options (query and variables at least) plus a parseResponse function which will be called with the query results.

export default function myQueryBuilder(introspectionResults, options) {
    // Do what you want with the introspection results
    return function(aorFetchType, resource, params) {
        const query = generateAQueryFromIntrospection(aorFetchType, resource, params);
        const variables = getVariables(aorFetchType, resource, params);
        const parseResponse = getParseResponseFunction(aorFetchType, resource, params);

        return { query, variables, parseResponse);
    }
}

This should make full customization a lot easier.

aor-graphql-client-graphcool

Will supply the queryBuilder for graphcool

aor-graphql-client-simple

Will supply the queryBuilder for our simple implementation not tied to graphcool

[RFC] Make implementing different flavors of graphql easier

Ability to supply a graphql flavor object:

{
    GET_LIST: {
        operationName: (resource) => `getPageOf${pluralize(resource.name)}`,
        query: (operationName, fields) => gql`...`, // Returns the graphql query
        getParameters: (params) => ({}), // Returns an object of params which will be passed to query/mutation with Apollo
        parseResponse: (response, resource, apolloParams) => ({}) // Parse the response into the format expected by Admin-on-rest
    }
}

RangeError: Maximum call stack size exceeded

Hi, thanks for the awesome work.

I'm trying to follow the readme and I'm stuck with this error when loading the page:

buildFieldList.js?7695:69 Uncaught (in promise) RangeError: Maximum call stack size exceeded
    at Array.find (native)
    at eval (eval at <anonymous> (http://localhost:3000/webpack/development/webpack-bundle-949b87a75a60b8b8d5c9.js:9388:1), <anonymous>:69:34)
    at Array.map (native)
    at buildFieldListFromList (eval at <anonymous> (http://localhost:3000/webpack/development/webpack-bundle-949b87a75a60b8b8d5c9.js:9388:1), <anonymous>:64:8)
    at eval (eval at <anonymous> (http://localhost:3000/webpack/development/webpack-bundle-949b87a75a60b8b8d5c9.js:9388:1), <anonymous>:74:37)
    at Array.map (native)
    at buildFieldListFromList (eval at <anonymous> (http://localhost:3000/webpack/development/webpack-bundle-949b87a75a60b8b8d5c9.js:9388:1), <anonymous>:64:8)
    at eval (eval at <anonymous> (http://localhost:3000/webpack/development/webpack-bundle-949b87a75a60b8b8d5c9.js:9388:1), <anonymous>:74:37)
    at Array.map (native)
    at buildFieldListFromList (eval at <anonymous> (http://localhost:3000/webpack/development/webpack-bundle-949b87a75a60b8b8d5c9.js:9388:1), <anonymous>:64:8)

This is my admin page:

import React, { Component } from 'react';
import { buildApolloClient } from 'aor-simple-graphql-client';

import { Admin, Resource } from 'admin-on-rest';
import { Delete } from 'admin-on-rest/lib/mui';

import { CustomerList } from './customers';

class AdminPage extends Component {
  constructor() {
    super();
    this.state = { restClient: null };
  }
  
  componentDidMount() {
    buildApolloClient({ clientOptions: { uri: '/queries' } })
      .then(restClient => this.setState({ restClient }));
  }

  render() {
    if (!this.state.restClient) {
        return <div>Loading</div>;
    }

    return (
      <Admin restClient={this.state.restClient}>
        <Resource name='Customer' list={CustomerList} />
      </Admin>
    );
  }
}

export default AdminPage;

customer page:

import React from 'react';
import { List, Datagrid, TextField } from 'admin-on-rest';

export const CustomerList = (props) => (
  <List {...props}>
    <Datagrid>
      <TextField source="id" />
    </Datagrid>
  </List>
);

GraphQL query and it's result:

// query
{
  getPageOfCustomers(page: 0, perPage: 10, sortField: "", sortOrder: "", filter: "") {
    items {
      id
    }
    totalCount
  }
}
// response
{
  "data": {
    "getPageOfCustomers": {
      "items": [
        {
          "id": "1"
        }
      ],
      "totalCount": 1
    }
  }
}

[RFC] Extract realtime saga in its own package

It might be interesting to extract and refactor the real time saga in order to ease its usage for other client implementations.

Proposed API is:

import realtimeSaga from 'aor-realtime';

const observeRequest = (fetchType, resource, params) => {
    // Use your apollo client methods here or sockets or whatever else including the following very naive polling mechanism
    return {
        subscribe(observer) {
            const intervalId = setInterval(() => {
                fetchData(fetchType, resource, params)
                    .then(results => observer.next(results)) // New data received, notify the observer
                    .catch(error => observer.error(error)); // Ouch, an error occured, notify the observer
            }, 5000);

            const subscription = {
                unsubscribe() {
                    // Clean up after ourselves
                    clearInterval(intervalId);
                    // Notify the saga that we cleaned up everything
                    observer.complete();
                }
            };

            return subscription;
        },
    };
};

const customSaga = realtimeSaga(observeRequest);

Supply your own queries and mutations confusion

Hi, I followed the documentation about this theme but I don't know where place my queries constant. I tried placing the queries constant on buildApolloClient options but doesn't work:

const queries = {
  Post: {
    // Is an example, but doesn't works.
    CREATE: () => gql`
        mutation createPost($data: String, $myCustomVar: String){
            createPost(data: $data, myCustomVar: $myCustomVar) {
                id
            }
        }
    `
  }
}

buildApolloClient({ queries })

I got the following error:

captura de pantalla 2017-03-22 a las 3 28 11 p m

I'm doing something wrong but I do not know what, thanks for the support.

Support for subfields

Hi I have problems when I trying to use a Schema with sub-fields, the error is the next:

message: 'Field "user" of type "[Post]" must have a selection of subfields. Did you mean "user { ... }"?

Looks easy to fix, but on this package is very complicated. Please look my schema and more stuff for understand more.

Part of my Schema:

type Post {
   id: ID
   name: String
   user: User
}

type User {
  id: ID
  name: String
  email: String
}

type getPageOfPosts{
  items: [Post]
  totalCount: Int
}

query  {
  getPageOfPosts(page: Int, perPage: Int, sortField: String, sortOrder: String, filter: String): getPageOfPosts
}

schema {
  query: Query
}

The query sent automatically:

query getPageOfPosts($page: Int, $perPage: Int, $sortField: String, $sortOrder: String, $filter: String) {
  getPageOfPosts(page: $page, perPage: $perPage, sortField: $sortField, sortOrder: $sortOrder, filter: $filter) {
    items {
       id
       name
       user
    }
    totalCount
    __typename
  }
}

Query expected (Items part):

...

items {
   id
   name
   user {
     id
     name
     email
   }
}

...

Thanks for your support!

Can't find the repo on the npm registry

Hi, first of all, thanks for building this!

I am trying to install it via npm but the repo is not found:

'error Couldn't find package "aor-simple-graphql-client" on the "npm" registry.'

No introspection data for resources issue

Hi.

I've encountered a problem while working with the client. The thing is I can see queries are fetched in introspection, but they are not occurring while trying to fetch resource list.

Basing on readme, here's some code of mine

// users/index.js
import React from 'react';
import { List, Datagrid, TextField } from 'admin-on-rest/lib/mui';

export const UserList = props => (
    <List {...props} sort={{ field: 'created_at', order: 'DESC' }} perPage={25}>
        <Datagrid bodyOptions={{ stripedRows: true, showRowHover: true }}>
            <TextField source="id" />
            <TextField source="name"/>
        </Datagrid>
    </List>
);

// App.js
import React, { Component } from 'react';
import { buildApolloClient } from 'aor-simple-graphql-client';
import { Admin, Resource } from 'admin-on-rest';
import { UserList } from './users/index';

import './App.css';

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

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

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

        return (
            <Admin
                restClient={restClient}
            >
                <Resource name="Users" list={UserList} />
            </Admin>
        );
    }
}

export default App;

screen shot 2017-07-05 at 20 28 00
Fetched queries by introspection

screen shot 2017-07-05 at 20 24 06
Errors

screen shot 2017-07-05 at 20 30 01
Server introspection response

I appriciate any advice from you.

"Cannot read property 'GET_LIST' of undefined" or incomplete README

having followed the README guide, I am a little frustrated.

I can see the graphql introspection query in my network tab and It does get all the type and inputs from my schema, but nothing for the queries and mutations.

{
  "queryType": {
    "name":"Query"
  },
  "mutationType": {
    "name":"Mutation"
  },
  //...
}

I have this

componentDidMount() {
      buildApolloClient({ clientOptions, introspection: introspectionOptions })
          .then(restClient => this.setState({ restClient }));
  }

where clientOptions is

const apiUrl = process.env.REACT_APP_API_URL
export const clientOptions = {
  uri: `${apiUrl}/graphql`
}

and introspectionOptions is the same as in README :

import pluralize from 'pluralize'

export const introspectionOptions = {
  includeTypes: null, // Either an array of types to include or a function which will be called with each OBJECT type discovered through introspection
  excludeTypes: null, // Either an array of types to exclude or a function which will be called with each OBJECT type discovered through introspection (`Query` and `Mutation` are excluded anyway)
  includeQueries: null, // Either an array of queries to include or a function which will be called with each query discovered through introspection
  excludeQueries: null, // Either an array of queries to exclude or a function which will be called with each query discovered through introspection
  includeMutations: null, // Either an array of mutations to include or a function which will be called with each mutation discovered through introspection
  excludeMutations: null, // Either an array of mutations to exclude or a function which will be called with each mutation discovered through introspection
  excludeFields: null, // Either an array of fields to exclude or a function which will be called with each field discovered through introspection on a specific object (more details below)

  // This contains templates for defining the queries and mutations names which will also be used as the operations names
  templates: {
    GET_LIST: resourceType => `getPageOf${pluralize(resourceType.name)}`,
    GET_ONE: resourceType => `get${resourceType.name}`,
    CREATE: resourceType => `create${resourceType.name}`,
    UPDATE: resourceType => `update${resourceType.name}`,
    DELETE: resourceType => `remove${resourceType.name}`,
  },
}

Am I missing something ?

incompatible with current version of admin-on-rest

Listed in your package.json peerDependencies is a very old version of admin-on-rest.
"admin-on-rest": "~0.9.1"

Listed in your devDependencies is a different version.
"admin-on-rest": "~1.0.1"

The latest version of admin-on-rest depends on a newer version of redux-saga.
The error that is thrown when using [email protected] & [email protected] is
uncaught at rootSaga TypeError: (0 , _effects.all) is not a functionย 
redux-saga/redux-saga#995

Documentation issues regarding GraphCool

Hello gentlemans,

I've been trying to plug AOR on a graphcool backend for 2 days, and the documentation is driving me crazy.

It is mentioned that this package is not working for graphcool, and therefore that we should use the one linked. However, on the package you linked, it is said that the package is deprecated, and that we should now use GraphQL flavors (using aor-simple-graphql-client).

I found this package as well (https://github.com/marmelab/aor-graphql/tree/master/packages/aor-graphql-client-graphcool), but it seems that it's still in WIP because I didn't managed to get it completely working.

What current solution are we supposed to use for us to bridge graphcool with AOR ?

Btw, I have tried using aor-simple-graphql-client with GraphQL flavors, and miserably failed at it :(.

Have a nice day guys.

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.