Introducing Graphqelm, a Tool for Type-Safe GraphQL Queries

After an initial round of feedback and design iteration, I’m ready to share Graphqelm!
With the code generated from Graphqelm, your server responses are guaranteed to decode correctly without writing a single decoder. Check out this live code example on Ellie.

I built this library because I wanted the safety and simplicity for server requests that Style Elements brings to layouts. In particular, my design goals for this package were:

  • Type-safe GraphQL queries (if it compiles, it’s valid according to your GraphQL schema),
  • Build decoders for you in a seamless and failsafe way, and
  • Eliminate GraphQL features in favor of Elm language constructs where possible for a simpler UX (for example, GraphQL variables & fragments should just be Elm functions, constants, lets).

To try it out for yourself, check out the usage instructions on the github page. I love feedback, so please let me know what you think! And feel free to ask questions on #graphql in the elm slack.

32 Likes

This is really interesting. I’ve been writing out my queries as strings up to this point, and of course all the decoders. I’ll give this a try. Thanks for sharing!

3 Likes

Wonderful, I’d love to hear your thoughts when you do!

hey dillon!

let me start off by saying your package looks really wonderful and well-organized! awesome work.

looking at http://package.elm-lang.org/, it seems there are about 7 other graphql packages up to date with Elm 0.18. have you taken a look at these and/or spoken to their authors already? i’m wondering if there might be some duplication of effort going on here.

not to disparage your package, of course! i just always prefer for there to be one de facto way of doing things, when possible, and the GraphQL package situation right now seems a bit confusing.

1 Like

Hey @noahzgordon, thanks for the question! Perhaps I should make it more clear what differentiates my package from the other ones out there in my README as I’m sure this is the first question people will ask when they see this package.

I have looked at all the different offerings and spoken to some of the other package authors. What it comes down to is that there are 3 different approaches out there right now for Elm GraphQL packages:

1) No code-gen, DSL to build up a Decoder and Query with the same code

With these packages, there is no help to guarantee that your queries will be valid according to the schema.

  • jamesmacaulay/elm-graphql - this is the most popular GraphQL package right now
  • pro100filipp/elm-graphql - this is just a fork of jamesmacalulay’s package with some minor changes
  • ghivert/elm-graphql - this package is actually a special case of the no-code-gen approach, you write your decoders separately and it only helps you generate GraphQL requests.
  • Xerpa/elm-graphql - a fork of ghivert/elm-graphql with remote-data support.
  • chrisalmeida/graphqelm - similar to ghivert/elm-graphql's approach, this doesn’t deal with the decoders, it only builds requests.

2) Schema & Query Document => Generate type-safe code for that specific Query Document

With these packages, you give it a specific request and it will generate Elm code for only that request.

  • jahewson/elm-graphql-module - No Elm 0.18 support
  • base-dev/elm-graphql-module - Broken Elm 0.18 code generation This is a fork of jahewson/elm-graphql-module. It still depends on the original NPM module for codegen, so it is not in a functioning state.
  • M1chaelTran/elm-graphql - Labeled as a work in progress The readme says that it’s still being worked on at a bi-monthly hackathon.

3) Schema => Generate type-safe code for entire schema

  • dillonkearns/graphqelm - this is the only package out there that takes this approach. I built this package because I wanted to have the type-safety and simplicity that I love about my favorite elm packages!

Differing Goals

Here’s why I chose not to merge with existing packages.

jamesmacalulay/elm-graphql is the most popular GraphQL package right now (it’s under approach #1). James considered adding a whole-schema code generation feature like dillonkearns/graphqelm, but decided to abandon the idea and stick to approach #1, here’s the thread. I think these are different enough goals and approaches to warrant a different package, and I needed a whole new set of code to support this so it didn’t make sense to try to build off of this package either.

jahewson/elm-graphql-module had a lot of momentum behind it before Elm 0.18 (which it doesn’t yet support). I made a point about how, in my opinion, there’s no need for packages with approach #2 anymore when there is a solid package for approach #3, here’s that discussion.

Thanks again for the helpful question!

8 Likes

@dillonkearns thanks for this comparison, it is very useful. I’m keen to try your package.

However I wouldn’t say that there is no need for approach #2. In my case I would like to write a graphql query in a .graphql file using the graphql DSL instead of an Elm DSL, and have a package validate and generate Elm code from that. I miss this from working in React. But maybe this is just because I haven’t use an Elm DSL that feel easy and intuitive, will try your package and see if that changes this.

2 Likes

Yes, it is certainly subjective whether approach #2 is still useful. I hope that you’ll find that graphqelm is easy enough that it’s even nicer than this approach for your use case, though! I can’t think of a use case where I would prefer approach #2, because as code evolves over time I want to be able to make changes and refactor within Elm instead of tweaking the query in GraphQL. And I’ve found it quite discoverable to write the queries initially with the generated Graphqelm code as well.

If Elm had macros like say Clojure, approach #2 would be much more interesting. You could keep your queries in .graphql files, have them turn into Elm code at compile time without having to launch a command-line tool to generate the code, and easily tweak your queries interactively in the GraphiQL web interface.

But without macros keeping the generated code in sync seems too annoying to do queries in GraphQL.

2 Likes

Interesting idea. With good IDE support I think approach #3 is actually a nicer API discovery experience than the grpahiql interface. IDE support right now is decent but far from outstanding, but even so I find it quite nice using code completion to discover the API as I build code in Elm.

The great thing about GraphiQL is that you can make requests live against the API and get some results. So the equivalent with method #3 would be a smarter REPL that would help you hit the API interactively.

1 Like

I’ve been using this package while learning elm. Very nice! The examples in the repo were helpful to get started.

2 Likes

I’ve started to use this package. Is awesome for type safe queries and mutations! Seamless elm integration

2 Likes

A year later, has the landscape changed at all? Thinking of diving into dillonkearns’ elm-graphql

1 Like

Hi! Something must have gone wrong with the automatic topic locking here. It should not have been possible to reply a year later. We do this because it’s really easy for nobody to respond when a topic is reopened after a year. I guess it’s easy to see here since you haven’t got an answer after four days!

The answer is basically: Dillon’s package is the best way to do GraphQL queries in Elm. Have fun! If you have further questions, please create a new thread. :smile:

2 Likes