Giter Club home page Giter Club logo

plugin-graphql's Introduction

Vuex ORM

Vuex ORM

Travis CI codecov npm JavaScript Style Guide License


πŸ”₯ HEADS UP! Currently, Vuex ORM Next project is on going, and we are hoping it is going to be the foundation of the version 1.0.0 release. We're not planning to add features to current v0.36.3 due to focusing more on Vuex ORM Next development. If you're new to Vuex ORM, please try out Vuex ORM Next.


Vuex ORM is a plugin for Vuex to enable Object-Relational Mapping access to the Vuex Store. Vuex ORM lets you create "normalized" data schema within Vuex Store with relationships such as "Has One" and "Belongs To Many" like any other usual ORM library. It also provides fluent API to get, search and update Store state.

Vuex ORM is heavily inspired by Redux recipe of "Normalizing State Shape" and "Updating Normalized Data". Learn more about the concept and motivation of Vuex ORM at What is Vuex ORM?.

Sponsors

Vuex ORM is sponsored by awesome folks. Big love to all of them from whole Vuex ORM community πŸ’•

Super Love Sponsors

Peter TΓ³th Mario Kolli Cannikan Andy Koch Dylan Copeland

Big Love Sponsors

geraldbiggs Cue Kazuya Kawaguchi jShaf ibrainventures

A Love Sponsors

George Chaduneli bpuig John mean-cj Jeffrey Soong

Documentation

You can check out the full documentation for Vuex ORM at https://vuex-orm.org.

Questions & Discussions

Join us on our Slack Channel for any questions and discussions.

Although there is the Slack Channel, do not hesitate to open an issue for any question you might have. We're always more than happy to hear any feedback, and we don't care what kind of form they are.

Examples

You can find example applications built using Vuex ORM at;

Plugins

Vuex ORM can be extended via plugins to add additional features. Here is a list of available plugins.

Also, you can find a list of awesome things related to Vuex ORM at Awesome Vuex ORM.

Contribution

We are excited that you are interested in contributing to Vuex ORM! Anything from raising an issue, submitting an idea of a new feature, or making a pull request is welcome! Before submitting your contribution though, please make sure to take a moment and read through the following guidelines.

Pull Request Guidelines

When submitting a new pull request, please make sure to follow these guidelines:

  • For feature requests: Checkout a topic branch from dev branch, and merge back against dev branch.
  • For bug fixes: Checkout a topic branch from master branch, and merge back against master branch.

These rules also apply to the documentation. If you're submitting documentation about a new feature that isn't released yet, you must checkout the dev branch, but for non-functional updates, such as fixing a typo, you may checkout and commit to the master branch.

Scripts

There are several scripts to help with development.

$ yarn build

Compile files and generate bundles in dist directory.

$ yarn lint

Lint files using a rule of Standard JS.

$ yarn test

Run the test using Jest.

$ yarn test:watch

Run the test in watch mode.

$ yarn test:perf

Run the performance test.

$ yarn coverage

Generate test coverage in coverage directory.

$ yarn docs

Build and boot documentation server with VuePress.

License

The Vuex ORM is open-sourced software licensed under the MIT License.

plugin-graphql's People

Contributors

cameroncf avatar cwirz avatar dependabot[bot] avatar douglance avatar josx avatar kevinmarrec avatar kiaking avatar ktsn avatar ldiebold avatar phortx avatar romtorres avatar stevefan1999-personal avatar timvandesteeg avatar tldmain avatar toadkicker avatar uplus avatar wittestier 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  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  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

plugin-graphql's Issues

Querying connections: nodes, edges>nodes vs nothing

It seems there are 3 ways out there how you can query a field with multiple records (connections):

  1. Via a nodes field (this is what the plugin does currently)
users {
  count
  nodes {
    id
    email
    name
  }
}
  1. Via a node field within a edges field
users {
  count
  edges {
    node {
      id
      email
      name
    }
  }
}
  1. Via none of these
users {
  id
  email
  name
}

Due to the fact that some APIs support 1 and 2, some support only 2 and some only support 3, it makes the usage of this plugin difficult, due to the fact that we hard implemented case 1.

Maybe we should implement a cascading detection of how the query should look like based on the schema. The GraphQL Plugin could automatically detect whether nodes is supported or if not whether edges > node is supported and if not fallback to use neither of those.

Additionally there should be a options flag where you can enforce one of these modes.

However for me it's not clear what the standard way is and what makes sense, which is something we have to find out.

Thanks to @oligus for reporting!

Optimistic UI

The Apollo-Client supports Optimistic UI. It would be nice when this plugin would support that too.

We have to think about what this means and how this support could look like.

Playground

To make the development on this plugin easier, it would be nice if there is some playground: a graphql api server and a vue frontend where we can test vuex-orm-apollo while developing without the requirement to use an own app.

For server we could use https://github.com/graphcool/graphql-server-example.

$id and $isPersisted are sent as arguments

When I want to save a Object A which belongsTo B which belongsTo C then the fields $id and $isPersisted of C are sent to the server.

This is probably because C is not sent to transformOutgoingData, which is a bug.

Custom Mutation Args broken

this.record.$mutate({ name: 'reorderItems', args: { itemIds } }); doesn't work. The arguments are completly f*cked up

Filter with String Array

If you try to filter for array items it handles the parameter as an Object, which it isn't.

Example: CarModel.dispatch('fetch', { filter: { carMake_slug_list: 'audi' }}) works fine while CarModel.dispatch('fetch', { filter: { carMake_slug_list: ['audi', 'bmw'] }}) doesn't.

I got it working with catching the following part (which isn't the solution) in the transformer.ts:

try {
  const arrayModel = context.getModel(singularize(key));
  returnValue[key] = value.map(v => this.transformOutgoingData(arrayModel || model, v));
} catch (e) {
  returnValue[key] = value;
}

Using GraphQL AST syntax tree object version of query in `simpleQuery` method

apollographql/graphql-tag package has webpack loader which preprocesses string queries into GraphQL AST object during import from separated *.graphql files.

And it would be helpful to add support of using GraphQL AST object in simpleQuery and simpleMutation methods.

import query from 'query.gql'
// query now is a GraphQL syntax tree object
console.log(query)
// {
//   "kind": "Document",
//   "definitions": [
//     {
//       "kind": "OperationDefinition",
//       "operation": "query",
//       "name": null,
//       "variableDefinitions": null,
//       "directives": [],
//       "selectionSet": {
//         "kind": "SelectionSet",
//         "selections": [
//           {
//             "kind": "Field",
//             "alias": null,
//             "name": {
//               "kind": "Name",
//               "value": "user",
//               ...
const result = await store.dispatch('entities/simpleQuery', {
  query
});

Custom queries

Just like the custom mutations it should be possible to send custom queries too.

Create a common interface to support both GraphQL and REST

Good day!
I'm currently working on some new project and chose a Vue as frontend framework. After some research i found the VuexORM project as a perfect solution to organise data. But unfortunately it has no built-in communication with API backend. So i've found such an issue in the main VuexORM project and saw your posts about creating this plugin for adding communication with GraphQL backend. Thanks for this great work!
However GraphQL is not the only option and it would be certainly very useful to have an ability to communicate with REST API.
So i'm adding this issue here because the interface of your plugin in fact looks quite general and perfectly fits any backend API. Thus it's more logical to divide your plugin and add one more layer of abstraction which would represent the API methods of communication with backend (fetch, push, destroy and so on). And the very logic of the protocol (GraphQL or REST) move to separate modules.

Real GraphQL Server for the test suite

Currently we mock the response from a GraphQL Server for the tests, but that's not a good idea in long term. Errors in the mock responses can lead to undiscovered bugs in the lib.

It would be better to use Apollo to spawn a GraphQL schema in the test suite and use that for testing.

Is it possible to make support of graphile/postgraphile?

Hello, thanks for the great plugin!

I was wondering if it's possible to make it compatible with https://github.com/graphile/postgraphile tool?
It makes a graphql api from existing postgresql tables. This tandem would be awesome.

Data retrieving is working already, but there are minor differences in mutations, for example postraphile makes it this way:


input TodoInput {
  id: Int
  label: String!
  isCompleted: Boolean
}

input CreateTodoInput {
  clientMutationId: String
  todo: TodoInput!
}

type Mutation {
  createTodo(
    input: CreateTodoInput!
  ): CreateTodoPayload

...and so on.

Creating relations without Id field

My backend doesn't return the ids of the relations out of the box.

This should work:

color: this.hasOne(Color, 'color'),

It should fetch the relation from the color.id field.

Current behavior is that it's simply not working.

Saving data into vuex coming from django-graphene backend.

Hi,

First of all thank you for vuex-orm. For me is just a dream come true to be able to replicate a part of back-end data to front-end and using vuex-orm-graphql to be able to do int in one request. I think this is a amazing project.

Now i try to use vuex-orm-graphql plugin, and i have some issues in implementing it in my project.
I am sending following query:
screen shot 2018-07-30 at 14 36 15

And i receive the following response:
screen shot 2018-07-30 at 14 39 29

Until this point all is as expected.

I would like to save a list of articles into store.
Now i need somebody to point me in the right direction because everything that i had tried failed.
My last "working" aka no errors saved in the store:

screen shot 2018-07-30 at 14 45 47

Also tried to create articleModel and articlesModel that has a many relation to articleModel. Failed.
I do receive this in console:

Vuex-ORM: GraphQL Plugin Ignoring entity article because it's not in the schema.

I am doing something wrong and now i am out of ideas.

Error installing plugin

Trying to add plugin to vuex-orm and getting this error.
Node: v10.6.0
NPM: 6.4.1
typescript: 2.7.2

import VuexORM from '@vuex-orm/core';
import VuexORMGraphQL from '@vuex-orm/plugin-graphql';
import database from '~/store/database';

VuexORM.use(VuexORMGraphQL, {
  database,
  debug: process.env.NODE_ENV !== 'production'
});

Error: fetch is not found globally and no fetcher passed, to fix pass a fetch for
your environment like https://www.npmjs.com/package/node-fetch.
For example:
import fetch from 'node-fetch';
import { createHttpLink } from 'apollo-link-http';
const link = createHttpLink({ uri: '/graphql', fetch: fetch });

Non integer id broken with mutation

If a mutation returns a non integer id (like a relay node), a new record with id NaN is created.
I found this while debugging:

newData.id = parseInt(newData.id, 10);

Something like this might be better:

const newId = Number.parseInt(newData.id, 10);
if (!Number.isNaN(newId)) {
    newData.id = newId;
}

Number coerced to Int

With a schema using ID type, fetching a record via fetch coerces number type to Int.

Example query:

query PriceLists($maoId: ID) {
  priceLists(filter: {maoId: $maoId}) {
    nodes {
      id
      fromDate
      toDate
      active
    }
  }
}

variable:
{
  "maoId": 148
}

Fetching with:
const result = await PriceListsModel.fetch({maoId: 148})

Results in:

operationName: "PriceLists"
query : "query PriceLists($maoId: Int!) {
  priceLists(filter: {maoId: $maoId}) {
    nodes {
      id
      fromDate
      toDate
      active
      __typename
    }
    __typename
  }
}"

variables:{maoId: 148}

The coercion is probably made here: https://github.com/vuex-orm/vuex-orm-graphql/blob/544b2c91b8e5fbab74f329f7a1b8b0e1d005f1b7/src/graphql/query-builder.ts#L221-L222

Recursion detection for models is buggy

In the current implementation the plugin will never be able to generate the following query:

comments {
  posts {
     user { ... }
  }
  user { ... }
}

Because the querybuilder remembers what models are already in the query with a simple array and omits a model if it's already in the array. We rather need some kind of tree structure here.

Incorrect type for registration within VuexORM

Hello.

I'm trying to use this plugin but when I try to register it in VuexORM the type of VuexORMGraphQL is not Plugin.

import VuexORM from '@vuex-orm/core';

Vue.use(Vuex);

const database = new VuexORM.Database();

database.register(Answer, answers);
database.register(Question, questions);

import VuexORMGraphQL from '@vuex-orm/plugin-graphql';
VuexORM.use(VuexORMGraphQL, { database });

Argument of type 'typeof VuexORMGraphQLPlugin' is not assignable to parameter of type 'Plugin'.
  Types of property 'install' are incompatible.
    Type '(components: Components, options: Options) => VuexORMGraphQL' is not assignable to type '(components: Components, options: Options) => void'.
      Types of parameters 'options' and 'options' are incompatible.

Documentation

  • Setup VuePress and GitHub Pages
  • Introduction, Setup
  • GraphQL Schema Design
  • Fetch, Caching
  • Push, Persist, Destroy
  • Relationships
  • Eager Loading
  • skipFields
  • $isPersisted

Consume the schema

Theoretically this plugin could fetch the GraphQL schema initially to know how the queries/mutations are shaped and maybe even detect incompatibilities.

Following things could be optimized by leveraging the schema:

  • Whether a custom query/mutation type is a connection (multiple) or not
  • Which fields to skip due to the fact that these are not included in the schema
  • Determine types of generic attributes

More to come.

Support Graphene like filtering

Python Graphene does filtering like this:

query {
  # Note that fields names become camelcased
  allAnimals(genus: "cat", name_Icontains: "lion") {
    edges {
      node {
        id,
        name
      }
    }
  }
}

I think we should support that too as an alternative to the FilterType based filtering

Add version and linked state as debug logging

It would be nice when the plugin could print the version and whether it's linked or not. Like: [Vuex-ORM-GraphQL] Version 1.0.0-rc.8 (linked from /Users/superman/projects/vuex-orm-graphql)

Not sure if it's possible to determine whether the project is linked.

Mistaken `clone` function behaviour in QueryBuilder.buildQuery method on `src` version

Clone methods in dist/vuex-orm-graphql.esm.js version and src/graphql/query-builder.ts have different behaviours. It is probably the wrong behaviour in src/graphql/query-builder.ts which causes the argument arg property's value undesirable override in mutation.

Example

args = {
  id: '123',
  post: {
    title: 'Title'
  }
}

// after QueryBuilder.buildQuery('mutation', model, 'post', args, multiple, filter) call becomes

args = {
  id: '123',
  post: {
    __type: 'Post'
  }
}

All data inside post ({ title: 'Title' }) overrides with value { __type: 'Post' }

Dist files are very large

Is there any reason that the final dist files are so large? (905Kb) - it's significantly larger than vuex-orm!
It looks like all the devDependencies have been included in the build... unless I'm reading it wrong.

ID Type is interpreted as String Type

I have a mutation with following signature:

signIn(name: String!, marketPlaceId: ID!, password: String!)

But the plugin sends:

signIn(name: String!, marketPlaceId: String!, password: String!)

Load relationships on demand

Currently, all relational data is fetched eagerly.

This could potentially be a problem with related data that has vast amount of records. It is probably not always desirable to fetch all relational data of the parent model.

it would be great if we it were possible to somehow define what related data you want to fetch for that particular request.

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.