jakeblaxon / graphql-join Goto Github PK
View Code? Open in Web Editor NEWLicense: MIT License
License: MIT License
There are several features I'd like to include in version 1.0.0. Here's a list of some of my ideas.
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:
__param_publishedAfter
. This is uglier and harder to read so should be avoided if possible.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:
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.
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.
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).
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
}
}
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:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.