graphql-rust / graphql-client

Typed, correct GraphQL requests and responses in Rust
Apache License 2.0
1.13k stars 151 forks source link

Integrate with Juniper? #20

Open LegNeato opened 6 years ago

LegNeato commented 6 years ago

Hi! Super excited you are working on this and it looks great! The Juniper project has had an open request to build a graphql client for a while now. Is there an opportunity for the projects to collaborate? If it doesn't make sense to, no worries!

tomhoule commented 6 years ago

Thanks :) I have seen that issue and was planning to post there after I make a first proper release. I am all in favour of joining efforts to make the Rust GraphQL ecosystem awesome (I already really like Juniper!).

I don't have a clear idea on how to integrate from a technical perspective however, or I may not be unsterstanding properly, do you have something in mind? The plan is to make the client work with any spec-compliant server first, of course.

LegNeato commented 6 years ago

Awesome! I haven't looked too much into technical ways we could collab, just wanted to make sure Juniper was on your radar! The only thing off the top of my head would be validating the client with a Juniper schema in Rust rather than going through the GraphQL layer. This might be useful for cases where both your client and server are Rust to get compile-time correctness checks?

LegNeato commented 6 years ago

Also, if you want we could move this repo into the https://github.com/graphql-rust/ org when it is ready. The idea of that org is to organize all rust graphql stuff in one place (including a high-level website that goes over how to use all the projects and different trade-offs if there are multiple projects with different approaches).

tomhoule commented 6 years ago

Great! Yep we could think about that sort of features - there is already a sort of intermediate representation for schemas in graphql-client that I build from the two sources supported for schemas (the introspected json format and schemas written ith the GraphQL schema language) so it could just be a matter of adding whatever the Juniper internal representation of a schema is as a third source.

I'd also liike to make custom scalars as flexible as possible, and maybe it will make sense to have a deeper integration with Juniper there due to the shared language. For example I was wondering (I need to read the spec more closely) about things like custom scalars transported as raw bytes strings (over something with the same model as json but with binary fields, like CBOR or MsgPack).

There is also a CLI in this project - the only thing it does now is send the introspection query and output the JSON representation of the schema (like apollo-codegen), but maybe it could become more general-purpose.

As for moving the project under the graphql-rust organization to make it more discoverable, I like the idea, let's talk about it again once this library is usable :) I intend to publish and announce a 0.1 release next weekend at the latest. There are not many missing features left, it's more a matter of examples and documentation.

tomhoule commented 6 years ago

I just managed to spend a few hours working on the library and pushed out a 0.2. There are still a lot of important features left to cover before it can be considered mature but I still intend to keep actively maintaining and improving it.

I also made a PR to add graphql-client to the awesome-graphql repo and noticed they have an examples section. It would be really cool to have a pure Rust example there with a Juniper server and a small webassembly frontend using graphql-client.

LegNeato commented 6 years ago

Awesome! I'm hoping to get some time to contribute soon.

tomhoule commented 5 years ago

Hey @LegNeato, I am digging up this issue because I thought there would be time to iterate on my own before people start using the crate, and then we could worry about moving it to the graphql-rust organization. Since you are watching the project you might have noticed there have been a lot of external contributions in the last month or so, and that I had a hard time keeping up with reviews and giving feedback (it didn't help that I'm still in the process of moving to a new place).

This is a very good thing, but it now feels a bit selfish to keep the project under my own name, and I'd like to start involving new maintainers so I don't become a bottleneck. Does your offer of moving the repo to the graphql-rust orga still stand? (if you think it's ready)

theduke commented 5 years ago

Hey @tomhoule , the offer definitely still stands and we'd love to work together.

If you are OK with the move, you'll have to make me (or LegNeato) an admin of this repo. Then we can initiate the move to the graphql-rust org.

tomhoule commented 5 years ago

Great! I added you both as collaborators (not sure that amounts to admin, we'll see when the invites are accepted).

theduke commented 5 years ago

@tomhoule I accepted, you need to promote to admin now in Settings/Collaborators so I can initiate the move.

(ps: you will of course remain admin of this repo)

tomhoule commented 5 years ago

I can't find the setting in the collaborators tab. The help page suggests that you have to be a member of the target organization. Maybe you can already transfer, as a contributor?

LegNeato commented 5 years ago

Hmmm, I accepted and can't initiate a move either...I have no settings tab on graphql-client 😢

tomhoule commented 5 years ago

I looked again and there definitely no option to make contributors admins. If my understanding of the help page and the message github shows when I try to transfer the repo is correct, the owner of the repository needs to have the right to create repositories in the target organization. That would mean I could either transfer ownership to one of you, or I could do it myself provided I am part of the organization.

LegNeato commented 5 years ago

Looks like I am only a member, so I can't add you as part of the org:

screen shot 2018-10-01 at 12 16 56 pm

We'll need to wait for @mhallin or @theduke to add you or make me an owner.

LegNeato commented 5 years ago

@tomhoule you should have an invitation to join the org

tomhoule commented 5 years ago

It's done :)

LegNeato commented 5 years ago

Potentially interesting: https://github.com/davidpdrsn/juniper-from-schema

LegNeato commented 5 years ago

I just did a juniper PR that supports going from a juniper schema to the graphql schema language as well as a graphql_parser Document:

https://github.com/graphql-rust/juniper/pull/324

Hopefully it should help these projects work together!

LegNeato commented 5 years ago

FWIW latest master of juniper now has built in support for the introspection query. One can easily generate a schema.json for use with graphql-client:

https://github.com/graphql-rust/juniper/blob/master/docs/book/content/advanced/introspection.md

tomhoule commented 5 years ago

That's great! I wonder if we could make the process more convenient on the graphql-client side. I think we need to compile the juniper schema, introspect (at runtime) and generate the code for the client from there no matter what. I can't see a way to compile the server and generate the client code in one pass.

LegNeato commented 5 years ago

I was thinking users make a workspace with two crates:

And then have my-frontend have a dev dependency on my-backend. Then in build.rs of my-frontend run juniper::introspect(MyBackendSchema) and write the schema.json? I haven't actually tried but was planning to tonight.

LegNeato commented 5 years ago

With a build system like buck/bazel you could have a CLI tool depend on my-backend, generate a binary, run the binary via a genrule and output the schema.json, and then build my-frontend.

theduke commented 5 years ago

I think relatively decent solution for a workspace would be:

agausmann commented 4 years ago

I've found a pretty neat way to completely integrate juniper with graphql-client in my full-stack webapp, I hope it can be useful for you all as well.

(Repository)

My app is split into two crates - frontend and backend. The backend hosts the database and the GraphQL API that's built with juniper, and I plan to use graphql-client in the frontend to handle queries. Here's the important parts that make it all work:

This is all done automatically, and works exactly as you'd expect. There are a few downsides: it requires you to manually install graphql_client_cli, there's no listing of the queries in the Rust source code (though you can still see them with cargo doc), and it's difficult to organize the resulting query objects into any kind of module structure.

It might be possible to make it work with #[derive(GraphQLQuery)], which would resolve all three of these problems, but it's difficult to pass the complete path of the schema.json file to the derive macro if it's generated by a build script. Cargo recommends that build scripts should not modify any file outside of OUT_DIR, but you can't currently pass an output file path to the macro, something like

#[graphql(schema_path = concat!(env!("OUT_DIR"), "/schema.json"))]

isn't legal.

The easiest way to do something like this would be to have another attribute parameter, something like schema_output_path, that takes a relative path and generates the concat! expression internally.

tomhoule commented 4 years ago

A special derive attribute argument to get the schema from OUT_DIR should be doable, I'd be happy to have an issue/PR for it if it helps your use-case!

agausmann commented 4 years ago

Turns out it's not that simple, since the proc-macro doesn't have access to OUT_DIR. I was mistaken, the proc macro does have access to the crate's environment.