juniper
juniper copied to clipboard
Feature: merge object definitions
File one
graphql_object!(QueryRoot: Pool<ConnectionManager<PgConnection>> |&self| {
field constant(&executor, id: String) -> FieldResult<Option<Constant>> {
......
}
});
File two
graphql_object!(QueryRoot: Pool<ConnectionManager<PgConnection>> |&self| {
field ssssss(&executor) -> FieldResult<Vec<Constant>> {
.....
}
});
Combining file
use juniper::RootNode;
pub struct QueryRoot;
pub struct MutationRoot;
pub type Schema = RootNode<'static, QueryRoot, MutationRoot>;
pub fn create_schema() -> Schema {
Schema::new(QueryRoot {}, MutationRoot {})
}
Obviously this aint working because of conflicting implementation of QueryRoot. Any suggestion how to go around this? I do not really want a super huge Schema file with all objects in it ! :/
Nesting works for me, but adds complexity to the ql. So any suggestions till appreciated.
@trsh Typically you only have one root then have nested objects within it it, that is,the graphql schema must contains a single graphql object, it cannot be an array of objects and so forth. This being said you can get around this a bit if you need to by setting up a proxy via nginx or apache so that each namespace points to a different graphql instance (but I kind of warn against this), but are you sure you just don't want.
file_1.rs
use file_2::File2Obj;
graphql_object!(QueryRoot: Pool<ConnectionManager<PgConnection>> |&self| {
field constant(&executor, id: String) -> FieldResult<Option<Constant>> {
......
}
field file_2(&executor) -> FieldResult<File2Obj> {
// logic to generate File2Obj
}
});
file_2.rs
graphql_object!(File2Obj: Pool<ConnectionManager<PgConnection>> |&self| {
field ssssss(&executor) -> FieldResult<Vec<Constant>> {
.....
}
});
Or if that isn't the case can you specify what you are trying to achieve via the query and I can give a suggestion on how to do so.
Nesting worked out fine form me
I'd still like to keep this open as a feature request because I want the same functionality of merging two separate object definitions into one.
@theduke cool
I also think this should be supported! I decided to use nesting, but this could be a very neat feature to have
+1
Same here, came looking for laying out multiple graphql endpoints to different files by business logic rather than dump everything to one file.
Another one. I'm planning to build a fairly large API with lots of fields. All data objects have a parent object for categorization. Something like that:
categoryOne {
objectOne { ...data }
objectTwo { ...data }
}
categoryTwo {
objectOne { ...data}
}
And each category can have 10+ fields, so I don't want to have them all in the same file.
I could try to implement this, but my Rust skills are a bit rusty (haha get it)(sorry) and I'm not familiar with the code base nor do I remember much about how macros work, so I'm not sure if I should. :smile:
This could be an extension to the GraphQLObject custom derive.
It would look something like this:
use objects::{ObjectOne, ObjectTwo, ...};
#[derive(juniper::GraphQLObject)]
struct CategoryOne {
#[juniper(merge)]
obj1: ObjectOneQuery,
#[juniper(merge)]
obj2: ObjectTwoQuery,
}
The custom derive code would need to build the code for impl GraphQLType for Query
The GraphQLType docs show a pretty good example of how the trait works.
The problem here is that we wouldn't know the structure of the merged types at compile time, so the impl would have to dynamically compute the info or the field resolver logic.
-
GraphQLType::meta(): this would have to call::meta()for each of the merged types and merge the result together. This is also the only time we could warn about field name conflicts by panicking. -
GraphQLType::resolve_field()would then have to decide which child typesresolve_field()must be called. For performance, there should be a lookup table here that is only created once.
The code for the custom derive is here: https://github.com/graphql-rust/juniper/blob/master/juniper_codegen/src/derive_object.rs.
The code would need to be extended to detect the merge(...) part of the attribute and then generate the appropriate code.
I'm happy to give more guidance here or on Gitter if you want to tackle it, @jgillich .
@theduke Thank you, this is great! I'm not sure when I'll get to this, but I'll let you know in case I need any help.
I'd love to be able to do something like this to avoid cramming everything in one file in big apps. Happy to help out on a PR anytime.

I tweeted to see if anyone is interested in this and looks like people would love to have it: https://twitter.com/vladkodmc/status/1162709927993008128?s=20
I'm looking to open a proof of concept PR for this soon.