Code Monkey home page Code Monkey logo

graphql-join's People

Contributors

jackson-blake avatar jakeblaxon avatar

Stargazers

 avatar  avatar

Watchers

 avatar

graphql-join's Issues

Version 1.0.0 Roadmap

Version 1.0.0 Roadmap

There are several features I'd like to include in version 1.0.0. Here's a list of some of my ideas.

adding parameter support

New fields should be able to specify parameters to help narrow the subquery. An example would be something like:

extend type Author {
  books(publishedAfter: String): [Book!]!
}

I believe the best way to handle this would be to specify multiple queries, stacked in order of priority. That way we don't limit ourselves to just one query for every case. The resolver string would look something like:

books(where: {authorId: {in: $id} publishedDate: {gte: $publishedAfter} })
booksByAuthorId(ids: $id) {
  id: authorId
}

If every variable in the first query is non-null, then graphql-join will run the first query but still use the last's selection set. If, however, one or more of the variables is null (i.e. if publishedAfter isn't provided), then graphql-join will fallback to the next query specified.

Some questions include:

  • should variables that correspond to params be prefixed to prevent potential name collisions? For example, something like __param_publishedAfter. This is uglier and harder to read so should be avoided if possible.

variable/field transforms

Variables should be able to be transformed, like converting strings to lower case, for example. We can use Lodash's api for transforms instead of inventing our own. There are a couple of use cases that come to mind:

  1. we want to transform a variable in the parameters, and it isn't included in the selection set.
  2. we want to transform a variable in the parameters, but not its corresponding field in the selection set.
  3. we want to transform a variable in the parameters and the selection set, but only the parent's selection field.
  4. we want to transform a variable in the parameters and the selection set, but only the child's selection field.
  5. we want to transform a variable in the parameters and the selection set, and both the parent's and child's selection field.
  6. we want to transform parent's and/or children's selection fields, but not the corresponding variable.

We don't need to cover every use case, but we should rank them by likelihood and try to cover as many as possible with a single solution that's still simple.

A potential solution I've thought of is using directives to specify transforms. Ideally these would be placed next to the selection fields we wish to transform. This would be the cleanest solution. The problem, though, is that you can't specify directives on query variables, so this solution wouldn't cover cases 1 and 2 (it could potentially cover case 2 with an extra flag in the directive, but that's not as intuitive).

A less simple solution, but one that would cover every case, is to allow the user to specify their own argsFromKeys and valuesFromResults functions. This wouldn't be specifiable in pure SDL, though, since it'd require the functions to be written in JS. It would also no longer be guaranteed to be type safe. Still, this solution may be necessary for really complex cases.

This feature still needs to be worked out.

single queries (i.e. one query per parent)

graphql-join supports batched queries by default, but sometimes we don't care about the n+1 problem and actually want to make single queries. Sometimes this is the only possible solution because the child and parent don't share any key fields that we can match on. In this case, we can simply make a single query per parent to avoid custom matching logic.

Off the top of my head, I believe this can be achieved with a query directive that would look something like this:

booksByAuthorId(id: $id) @single

A selection set would not be needed in this case since we don't have to match on any keys. We should still use batch execution if possible, to prevent n+1 individual network requests.

get resolver object instead of transform

Since graphql-join uses the stitchSchemas method from graphql-tools under the hood, we can offer an option where we instead just return the generated resolvers for the stitchSchemas method and let the user pass them in on their own. This would prevent an extra layer of schema wrapping and boost performance (if the user is using their own stitchSchemas call as well).

handle query encapsulation

A common pattern may be to encapsulate a subschema's root fields inside a parent root field, such as in the graphql-mesh encapsulate transform. We should allow the user to specify at which level the root field begins. I imagine something like the following would work nicely.

subschemaQueries {
  query1 @root {
    field1
  }
}

handle nested keys

Sometimes the key we want to compare on isn't a scalar, but an object containing however many levels of nested scalars. We should allow the user to specify that we wish to compare on a nested key. Perhaps if we see a nested selection set, we can assume that we should flatten it to its scalars for comparison? For example, if we see something like:

books {
  authorName {
    first
    last
  }
}

we can assume that we want to compare on authorName.first and authorName.last, where the parent's corresponding first and last fields are top-level scalars. We therefore ignore the wrapping field authorName when making key comparisons, and treat it as if first and last were also top-level scalars in the child (Book).

Some questions to consider:

  • Is this intuitive? Would a new user unfamiliar with this library be able to understand what should happen intuitively?
  • How would we handle nested scalars in the parent?

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.