graphql-to-elm
validates GraphQL queries and converts them to Elm code.
Allowing you to use your queries and schema types in a type-safe way.
This package assumes that you use GraphQL query documents and a schema document to write your queries and schema in. Or that you have a way to generate these documents.
If you want to write your GraphQL queries in Elm have a look at dillonkearns/elm-graphql or jamesmacaulay/elm-graphql. For more options have a look at this discussion.
Suppose you have a GraphQL query file (myQuery.gql
):
query UserName {
user {
name
}
}
Then you create a code generation script (prebuild.js
for instance) like this:
const { graphqlToElm } = require("graphql-to-elm");
graphqlToElm({
schema: "./src/mySchema.gql",
queries: ["./src/myQuery.gql"],
src: "./src",
dest: "./src-generated",
}).catch((error) => {
console.error(error);
process.exit(1);
});
You run the code generation script (node prebuild.js
).
Then in your Elm code you can now do this (full code here):
import GraphQL.Errors exposing (Errors)
import GraphQL.Response exposing (Response)
import MyQuery
init : () -> ( String, Cmd Msg )
init _ =
( "", postOperation MyQuery.userName GotUserName )
type Msg
= GotUserName (Result Http.Error (Response Errors MyQuery.UserNameQuery))
update : Msg -> String -> ( String, Cmd Msg )
update msg _ =
case msg of
GotUserName (Ok (GraphQL.Response.Data data)) ->
( "user name: " ++ data.user.name, Cmd.none )
GotUserName (Ok (GraphQL.Response.Errors _ _)) ->
( "GraphQL error", Cmd.none )
GotUserName (Err _) ->
( "Http error", Cmd.none )
graphql-to-elm
does not assume anything about how you send your GraphQL operations to your GraphQL server.
If you are using GraphQL over http you can define a function to post your operations like this:
import GraphQL.Errors exposing (Errors)
import GraphQL.Operation exposing (Operation)
import GraphQL.Response exposing (Response)
import Http
postOperation : Operation any Errors data -> (Result Http.Error (Response Errors data) -> msg) -> Cmd msg
postOperation operation msg =
Http.post
{ url = "/graphql"
, body = Http.jsonBody (GraphQL.Operation.encode operation)
, expect = Http.expectJson msg (GraphQL.Response.decoder operation)
}
You'll need to have node/npm installed.
-
Install the generator node/npm package
graphql-to-elm
from the command line.
To add it to your project'spackage.json
as a dev dependency use this command:npm install --save-dev graphql-to-elm
-
Install the elm package
harmboschloo/graphql-to-elm
from the command line.
To add it to your project'selm.json
use this command:elm install harmboschloo/graphql-to-elm
-
Create a JavaScript file (for instance
prebuild.js
) similar to this one:const { graphqlToElm } = require("graphql-to-elm"); graphqlToElm({ schema: "./src/schema.gql", queries: ["./src/MyQueries1.gql", "./src/MyQueries2.gql"], src: "./src", dest: "./src-generated", }).catch((error) => { console.error(error); process.exit(1); });
-
You can run this file from the command line with:
node prebuild.js
Running this command will read and validate your schema and queries. And for every query file it will generate and Elm file in the destination folder with Elm types, encoders and decoders.
-
To use the generated files in your project you have to include the destination folder in the
source-directories
field of yourelm.json
. It should look something like this:"source-directories": [ "src", "src-generated" ],
-
Now you can import the generated Elm files in your project and use them.
For full usage examples see the examples folder or have a look at the test fixtures folder.
For every query document graphql-to-elm
will generate valid Elm types, encoders and decoders that you can use in your code.
It includes support for:
- operations (queries, mutations, subscriptions)
- operation names
- fragments
- inline fragments
- variables
- aliases
- directives
- enums
- custom scalar encoders and decoders
- custom enum encoders and decoders
- custom error decoder
- batched queries
schema: string | { string: string }
Filename of the schema document. Or the whole schema as a string.
enums?: { baseModule?: string} = {
baseModule: "GraphQL.Enum"
}
Options for generating union types from GraphQL enums. 'baseModule' is the base module name for the union types.
queries: string[]
Array of filenames of the query documents.
src?: string = "."
Base folder of the queries.
dest?: string = "src"
Destination folder for the generateed Elm files.
interface TypeEncoders {
[graphqlType: string]: TypeEncoder;
}
interface TypeEncoder {
type: string;
encoder: string;
}
scalarEncoders?: TypeEncoders = {}
Scalar type encoders.
enumEncoders?: TypeEncoders = {}
Enum type encoders.
interface TypeDecoders {
[graphqlType: string]: TypeDecoder;
}
interface TypeDecoder {
type: string;
decoder: string;
}
scalarDecoders?: TypeDecoders = {}
Scalar type decoders.
enumDecoders?: TypeDecoders = {}
Enum type decoders.
errorsDecoder?: TypeDecoder = {
type: "GraphQL.Errors.Errors",
decoder: "GraphQL.Errors.decoder"
}
operationKind?: "query" | "named" | "named_prefixed"
Send the full query to the server or only the operation name.
The operation name can be prefixed with the query filename: [filename]:[operationName]
.
log?: (message: string) => void
Callback for log messages. Set to null
to disable.