jamesmacaulay / elm-graphql

A GraphQL library for Elm
http://package.elm-lang.org/packages/jamesmacaulay/elm-graphql/latest
BSD 3-Clause "New" or "Revised" License
313 stars 19 forks source link

Generate Elm modules from GraphQL queries and mutations #25

Open jamesmacaulay opened 6 years ago

jamesmacaulay commented 6 years ago

People want to be able to write their queries and mutations in GraphQL. I previously thought that #17 would be a worthwhile stepping-stone to this, but ongoing discussion has made it more clear that it's just not worth it.

Requirements:

welf commented 6 years ago

I think as a first step you can do it as web-service like for JSON decoding. User posts GraphQL API endpoint and his query or mutation, the web-service sends an introspection query to fetch the schema and generates a query or mutation with all imports and types/type aliases he needs for it.

jamesmacaulay commented 6 years ago

There are at least two independent streams of work here:

I've started on the query parsing task because it's of a manageable size for me at the moment. The analysis and code generation are bigger problems. I have a rough idea about what a solution could look like, but there are lots of hairy details yet to sort out.

jamesmacaulay commented 6 years ago

@welf I didn't see your comment before my last post – yes, I'd like to make a tool like that, and it should be simpler to build than the command-line wrapper because it can all be Elm-in-the-browser. However, either way, I think most of the work to be done is in the logic of parsing, analysis, and code generation.

jamesmacaulay commented 6 years ago

I've pushed a document-parser branch with a work-in-progress of a parser for query/mutation documents. Right now it just parses simple selection sets (no fragments). You can use elm-reactor with the demo app in the QueryParserDemo folder to try out the parser with different inputs.

jamesmacaulay commented 6 years ago

The document-parser branch should now parse all valid GraphQL documents. The syntax error messages are probably not very helpful right now, but at least it works!

Before incorporating this into a release, I will make some fuzz tests that generate valid document ASTs and verify serialize/parse round-trip equality.

jamesmacaulay commented 6 years ago

I've started on the task of analyzing document/schema pairs for code generation, and quickly decided that the best first step is to implement document validation. Not only is it perfectly reasonable to expect that this library should validate your query/mutation document against your schema before generating code from it, but most of the analysis logic required for code generation is also required for validation.

Validation is very well defined in the GraphQL spec, which means that the work is pretty straightforward (if a bit tedious at times). Once that work is done, we'll have a nice toolbox of functions that can be reused to analyze documents for the purposes of code generation. I've got some untested work-in-progress code in the document-validation branch, which builds on top of the document-parser branch:

https://github.com/jamesmacaulay/elm-graphql/compare/document-parser...document-validation

Vynlar commented 6 years ago

@jamesmacaulay I've looked at the work you've done on the document-validation branch in addition to looking over the validation section you linked in the GraphQL spec. I've noticed that there are some things we can validate independent of the schema, but others require information from the schema, for example: Field Selections on Objects. Upon noticing this, I searched around more and see that you already have a Schema module and decoder for it. Is this Schema module actually used in the existing library or have you written it purely in anticipation of needing it later (more accurately: now)?

anagrius commented 6 years ago

I am rooting for you guys. This would be great to have.

jamesmacaulay commented 6 years ago

@Vynlar Sorry for the delayed response. The Schema module is not currently used by the package. I think it was the first thing I wrote for the package, thinking that I would have a bunch of schema-using features right away, but in the end I shipped 1.0 with just the query builder and no schema stuff. I kept it around because it was still good well-tested code that I knew I'd want to use later/now.