Skip to content
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

Determine if Juniper should support alternate representations #328

Open
LegNeato opened this issue Mar 5, 2019 · 9 comments
Open

Determine if Juniper should support alternate representations #328

LegNeato opened this issue Mar 5, 2019 · 9 comments

Comments

@LegNeato
Copy link
Member

LegNeato commented Mar 5, 2019

Currently Juniper has no concept of the GraphQL Schema Language / SDL (referred to as "SDL" from now on). There is no way in Juniper to go from a schema defined in Rust to the SDL representation of it and vice versa.

Some 3rd party GraphQL tools work with the SDL and thus would not work with Juniper. More often than not, many of those tools support introspection query's output (usually in a file called schema.json) as well. Juniper "supports" the introspection query, as it is a standard GraphQL query that any client could do, though we have a task to make it more ergonomic.

The reference GraphQL server Graphql.js includes support for:

  • Doing everything in JS
  • Defining in JS and converting to SDL
  • Defining in SDL and converting to JS
  • Built in introspection query
  • Introspection -> JS

In fact, they explicitly test that you can go around between all these representations and have the same result.

In the Rust world we have:

So we need to decide if we follow GraphQL.js and include all the functionality in Juniper or we say Juniper is the "Rust-only" world above and everything else is handled in other crates (either in this workspace or in their own projects). I'm also not even sure we can include everything, as we need to do some work at compile time rather than runtime like GraphQL.js does.

/cc @theduke @mhallin @tailhook @davidpdrsn @tomhoule

(originally discussed in #324)

@davidpdrsn
Copy link
Contributor

From #324

Is it a view of the schema one would reasonably expect juniper to handle? Or is it a nice-to-have that isn't intrinsic to how juniper does things.

I would say this is something juniper should handle. Having an actual schema file that describes your API is one of the key things that intrigues me about GraphQL. It also feels like the "Rusty" approach because it puts greater emphasis on type safety, something I value a lot.

At the place where I work we're soon going to be experimenting with replacing parts of our Ruby on Rails API with Rust + GraphQL. For us being able to go from SDL to Rust would fit our workflow well I think. When the backend and mobile teams meet to decide the spec for some new feature we are going to build, we would add new fields/types to our schema. The mobile devs can then start using the schema right away to build queries in whatever way their language and tools allows for. The backend team can take the schema, "convert" it to Rust and fill in the blanks.
While I don't have lots of experience with this workflow (yet) I think it is going to work well.

Having the whole schema available for juniper would also allows you to make things like type safe look aheads. Not sure this would be possible if the schema wasn't known at compile time.

@LegNeato
Copy link
Member Author

LegNeato commented Mar 7, 2019

Why not do the opposite (define in rust and have the schema file be a view into what rust has defined)? That's what I am doing, as you get nice things like autocomplete in your editor without having to teach it SDL, easy grepability, etc. Plus, you can add lint rules for your graphql logic without having to add a graphql-specific framework. I try to stay in rust as much as possible. I use rust as the source of truth and see the SDL as serialization format that graphql tools outside of rust can use.

I understand things may be different for greenfield development like I am currently doing.

@LegNeato
Copy link
Member Author

LegNeato commented Mar 7, 2019

I love the idea of QueryTrails btw

@theduke
Copy link
Member

theduke commented Mar 7, 2019

After some thought, I do think it makes sense to be inclusive here and support all the possibilities outlined by LegNeato.

While I personally I am not a big fan of the Schema -> Rust workflow, I think many find it easier to work with. Also, as @davidpdrsn mentioned, sometimes you have the schema as the source of truth and implement both clients and servers based on that schema, or a subset of a schema in case of nested/forwarding servers.
The other attempt at a GraphQL server also used this workflow (https://github.com/nrc/graphql).

I think it makes sense to include the juniper_from_schema functionality into the main crate. (With some adaptations. I'm not a fan of their use of #[xx] Rust style annotations in the schema, since that breaks other tools. )

A general AST with conversion functionality would also make the implementation of graphql-client much easier I think.

@tomhoule
Copy link
Member

From the perspective of graphql_client, ingesting the GraphQL AST or the introspected schema in JSON form is about 100 lines each, so adding new sources is not a problem. The only obstacle to doing so now is that the schema and query representation juniper uses are private (this may have changed since I checked).

The internal representations (what the ASTs are converted to) for schema and query in graphql_client at the moment are just what it needs, so I am not sure they should be replaced, but I could be missing important reasons to do it.

In general I think the more representations for a GraphQL schema we support and can convert between the better, some people prefer an SDL-first workflow, others code-first.

In general the code sharing could be achieved by moving more things into juniper itself, but I would be more comfortable with modularizing juniper so other libraries can better interoperate with it. In particular I would like to have juniper_query_parser, juniper_schema, and (possibly in one of these) juniper_query_validation. The last one in particular would be very nice to have in graphql_client to do query validation with good error messages at compile time, without duplicating the effort between graphql_client and juniper.

@LegNeato LegNeato pinned this issue Sep 30, 2019
@theduke theduke unpinned this issue Oct 31, 2019
@vladinator1000
Copy link

vladinator1000 commented Jul 10, 2020

Coming from JS land I like how ergonomic the SDL approach is, but I'm not sure how I feel about the lack of specificity. i.e. How do we interpret a GraphQL Int. Default to an i32 by default? Same for ownership. 🤷‍♀️

@conradwt
Copy link

conradwt commented Jul 10, 2020

@vladinator1000 From the GraphQL spec, the size of a GraphQL Int should represent a value greater than or equal to -2^31 or less than or equal to 2^31. Thus, it's recommended that one use i32 here. If you're using values that fall outside this range, then it's recommended the one use a custom GraphQL scalar type. Int is a default GraphQL scalar type. At this time, I believe that the library doesn't support GraphQL Schema Definition Language (SDL) out of the box and one needs to use Rust types using the Rust language.

@LegNeato
Copy link
Member Author

Master supports the SDL as output and another project supports generating Juniper code from the SDL def. See first paragraph of https://graphql-rust.github.io/juniper/master/schema/schemas_and_mutations.html

@LegNeato
Copy link
Member Author

Ideally you have your schema in a lib crate. This can be used by a binary to dump a .graphql file for other tooling or in a build.rs to do other interesting stuff.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants