-
-
Notifications
You must be signed in to change notification settings - Fork 748
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Schema Stitching Part 1 #341
Comments
|
Path Spec The path components are separated by {
a {
b {
c {
.....
}
}
}
} Variables in the path are marked by curly braces The following variables exist:
For version one this is basically what can be accessed. |
Originally we wanted only to support remote schemas through IQueryExecuter. Since, we have covered more ground with our own use case for it we are now expanding and letting a remote schema be represented through ISchema with the default IQueryExecuter. This will give us the ability to write custom middleware for the remote schema that can convert types and/or other stuff. |
The path variable are now specified like the following:
|
Remote Schemas A remote schema is basically an external GraphQL schema to which the stitching layer will delegate queries. A remote schema always has a local schema representation. This local schema representation basically allows us to do all the validation etc. in memory without having to delegate to the server. Moreover, we do have the type context available to the stitching layer and we can write field middleware that further enhance results if needed. In order to do that we create a schema that only has a ISchema schema = Schema.Create(
FileResource.Open("Contract.graphql"),
c =>
{
c.RegisterType<DateTimeType>();
c.UseStitchingResolver();
});
IQueryExecutor executor = schema.MakeExecutable(b =>
b.UseStitchingPipeline("foo")); The schema name, in our case |
Subscriptions We will move stitching subscriptions to the next release. The idea here is that you can include subscriptions from the stitched schemas and then you are able to join in queries into the result. We need a new issue for that describing this in detail. |
Batching Similar to a DataLoader the stitching layer batches requests to the remote schema in order to reduce requests. Lets say we have two queries that the stitching layer wants to redirected to a remote schema: Query A: query foo($bar: String) {
foo(bar: $bar)
} Query B: query baz($qux: String) {
baz(qux: $qux)
} Then the query fetch_batch($__1_bar: String $__2_qux: String) {
__1: foo(bar: $bar)
__2: baz(qux: $qux)
} Since everything works similar to the DataLoader the consumer will not have to deal with the specifics here and can just consume the result. The batching will be included with 0.7.0-preview.35. We will add settings for this one so that the max complexity of a batch can be controlled. Caching We are moving the caching mechanisms to release 0.8.0. The caching basically that the same data is not fetched twice from the remote schema. We still haven't worked out all the edges here so we are not including caching into the 0.7.0 release. |
Additional Path Functionality Currently the selection path has now way to specify a type. So, lets say I want to you the node function use by many relay compatible schemas than I would have to specify the type that I want to fetch. Currently I only can say `node(id:$fields:id).FooBar' but in order to have access to FooBar I would have to specify the type of the node. Moreover, currently we cannot handle arrays with the path. So, even if I fetch an array with just one element I do not have a way to tell the stitching engine that I want the first or so on. For the latter we could use additional directives: type Query {
foo: String @delegate @skip(length: 1) @take(length: 1)
} |
Previews: |
Schema Stitching with Hot Chocolate
Hot Chocolate allows schema stitching through directives. There are basically two directives needed in the first proto-type.
@schema
The schema directive tells the stitching API to which schema/executer a field belongs.
@delegate
The delegate directive is a executable directive and basically describes how to fetch data from the other schema.
We call the schema that the Hot Chocolate is providing to the outside world local schema and the schemas to which Hot Chocolate is delegating a remote schema.
A remote schema is represented to the stitching API as
IQueryExecuter
and can basically be another local schema, a schema hosted by another GraphQL server over HTTP, a rest API, a database or even a file on your hard drive.The stitching API can request a specific
IQueryExecuter
by name through theIStitchingContext
.So, lets look at a simple example:
We have two schemas that we want to stitch together.
Remote Schema A
Remote Schema B
We now want our local schema to look like the following:
So, this schema is very easy to stitch. We just have to add a view directives to that and the query engine will do the rest.
@delegate
basically delegates the query to the annotated schema. By default delegate will delegate the request to that field to a query with the name of the field. In our query the local schema woul create the following query to fetch the field:But what when we have to fetch bar with the name of the
Foo
type from a deeper structure. In such a case we can use the delegate path attribute:if there had been a delegate like thsat than the query to the remote schema would have looked like the following:
We than take the data that is in bar and provide that to the query engine for integration.
In further iterations we will add more directives that are able to transform the resulting data.
So, how would we set this schema up? First, lets setup our stitching context:
So, in our example we specified two schemas with the graphql SDL. These schemas have a middleware that just returns foo or bar for every field. These schemas will act as our remote schemas. Each schema is referenced in a dictionary under a name that we will use in our local schema to refer to these remote schemas. The dictionary is than passed into out schema context.
So next we will setup our local schema that will stitch those two schemas together:
That is basically it. But, there is more ... you can like with every local schema override parts of your fields with resolvers etc. So, if you would like to add local calculated fields you can do so.
Or you could use directives to transform your results even further. Since our directives are working like a pipeline add your transforming directives to the and... Lets say we have a directive that makes every thing upper string.
So, this is basically version 1 of the Hot Chocolate schema stitching.
The text was updated successfully, but these errors were encountered: