All Projects → jamesmacaulay → Elm Graphql

jamesmacaulay / Elm Graphql

Licence: bsd-3-clause
A GraphQL library for Elm

Programming Languages

elm
856 projects

Projects that are alternatives of or similar to Elm Graphql

Neuron
A GraphQL client for Elixir
Stars: ✭ 244 (-23.03%)
Mutual labels:  graphql, graphql-client
Altair
✨⚡️ A beautiful feature-rich GraphQL Client for all platforms.
Stars: ✭ 3,827 (+1107.26%)
Mutual labels:  graphql, graphql-client
Apollo Android
🤖  A strongly-typed, caching GraphQL client for the JVM, Android, and Kotlin multiplatform.
Stars: ✭ 2,949 (+830.28%)
Mutual labels:  graphql, graphql-client
Reason Urql
Reason bindings for Formidable's Universal React Query Library, urql.
Stars: ✭ 203 (-35.96%)
Mutual labels:  graphql, graphql-client
Apollo Ios
📱  A strongly-typed, caching GraphQL client for iOS, written in Swift.
Stars: ✭ 3,192 (+906.94%)
Mutual labels:  graphql, graphql-client
36 Graphql Concepts
📜 36 concepts every GraphQL developer should know.
Stars: ✭ 209 (-34.07%)
Mutual labels:  graphql, graphql-client
Grafoo
A GraphQL Client and Toolkit
Stars: ✭ 264 (-16.72%)
Mutual labels:  graphql, graphql-client
Modelizr
Generate GraphQL queries from models that can be mocked and normalized.
Stars: ✭ 175 (-44.79%)
Mutual labels:  graphql, graphql-client
Nodes
A GraphQL JVM Client - Java, Kotlin, Scala, etc.
Stars: ✭ 276 (-12.93%)
Mutual labels:  graphql, graphql-client
Babel Blade
(under new management!) ⛸️Solve the Double Declaration problem with inline GraphQL. Babel plugin/macro that works with any GraphQL client!
Stars: ✭ 266 (-16.09%)
Mutual labels:  graphql, graphql-client
Graphql.js
A Simple and Isomorphic GraphQL Client for JavaScript
Stars: ✭ 2,206 (+595.9%)
Mutual labels:  graphql, graphql-client
Sgqlc
Simple GraphQL Client
Stars: ✭ 286 (-9.78%)
Mutual labels:  graphql, graphql-client
Hotchocolate
Welcome to the home of the Hot Chocolate GraphQL server for .NET, the Strawberry Shake GraphQL client for .NET and Banana Cake Pop the awesome Monaco based GraphQL IDE.
Stars: ✭ 3,009 (+849.21%)
Mutual labels:  graphql, graphql-client
Aws Mobile Appsync Sdk Ios
iOS SDK for AWS AppSync.
Stars: ✭ 231 (-27.13%)
Mutual labels:  graphql, graphql-client
Gqlify
[NOT MAINTAINED]An API integration framework using GraphQL
Stars: ✭ 182 (-42.59%)
Mutual labels:  graphql, graphql-client
Graphql Deduplicator
A GraphQL response deduplicator. Removes duplicate entities from the GraphQL response.
Stars: ✭ 258 (-18.61%)
Mutual labels:  graphql, graphql-client
Client Side Graphql
Stars: ✭ 119 (-62.46%)
Mutual labels:  graphql, graphql-client
Python Graphql Client
Simple GraphQL client for Python 2.7+
Stars: ✭ 133 (-58.04%)
Mutual labels:  graphql, graphql-client
Swift Graphql
A GraphQL client that lets you forget about GraphQL.
Stars: ✭ 264 (-16.72%)
Mutual labels:  graphql, graphql-client
Morpheus Graphql
Haskell GraphQL Api, Client and Tools
Stars: ✭ 285 (-10.09%)
Mutual labels:  graphql, graphql-client
elm-graphql logo

jamesmacaulay/elm-graphql

Travis-CI build status

A GraphQL library for Elm, written entirely in Elm.

The goal of this package is to provide a really good interface for working directly with GraphQL queries and schemas in Elm. Right now the main offering of the package is an interface for building up nested queries and mutations in a way that also builds up a decoder capable of decoding successful responses to the request. The package also provides a module for sending these requests to a GraphQL server over HTTP and decoding the responses accordingly.

The docs can be found here.

And here's an end-to-end example that builds a query, sends it to a server, and decodes the response.

Building requests

Building up a GraphQL query with this package feels a lot like building a JSON decoder, especially if you are familiar with the elm-decode-pipeline package. First you define type aliases for each of the nested record types you want to construct out of the response:

import GraphQL.Request.Builder exposing (..)
import GraphQL.Request.Builder.Arg as Arg
import GraphQL.Request.Builder.Variable as Var

type alias Photo =
    { url : String
    , caption : String
    }

type alias User =
    { name : String
    , photos : List Photo }

Then you build a query document:

userQuery : Document Query User { vars | userID : String }
userQuery =
    let
        userIDVar =
            Var.required "userID" .userID Var.id

        photo =
            object Photo
                |> with (field "url" [] string)
                |> with (field "caption" [] string)

        user =
            object User
                |> with (field "name" [] string)
                |> with (field "photos" [] (list photo))
        
        queryRoot =
            extract
                (field "user"
                    [ ( "id", Arg.variable userIDVar ) ]
                    user
                )
    in
        queryDocument queryRoot

The Document type can represent both query and mutation documents. It lets you do two important things:

  • generate GraphQL request documents to send to the server, and
  • decode JSON responses from the server.

Here's what the above Document looks like when you encode it to a string to be sent to the server:

query ($userID: ID!) {
  user(id: $userID) {
    name
    photos {
      url
      caption
    }
  }
}

To supply values for the variables used in the Document, you provide an Elm value that your variables can extract values from according to the getter functions supplied when you define the variables. In this example, the "userID" variable was defined as a string that's extracted from the userID field of some Elm record, so the following code is a valid way to create a Request with the required variable values supplied:

userQueryRequest : Request Query User
userQueryRequest =
    userQuery
        |> request { userID = "123" }

Assuming you've built a query that is valid for the server's schema, sending it to the server will result in a JSON response that can be decoded with a JSON decoder that is built up automatically along with the structure of the query. Here's what a JSON response for userQuery might look like:

{
  "data": {
    "user": {
      "name": "Lola",
      "photos": [
        {
          "url": "http://cdn.catphotos.com/lola.jpg",
          "caption": "Lola curling up on the chair"
        }
      ]
    }
  }
}

When it is decoded with the help of the decoder contained in userQuery, it becomes this:

{ name = "Lola"
, photos =
    [ { url = "http://cdn.catphotos.com/lola.jpg"
      , caption = "Lola curling up on the chair"
      }
    ]
}

Mutations are built just like queries, except that you wrap them up in a call to mutationDocument instead of a call to queryDocument. Here's an example of a mutation that logs in a user and extracts an auth token from the response:

type alias LoginVars =
    { username : String
    , password : String
    }


loginMutation : Document Mutation String LoginVars
loginMutation =
    let
        usernameVar =
            Var.required "username" .username Var.string

        passwordVar =
            Var.required "password" .password Var.string
    in
        mutationDocument <|
            extract
                (field "login"
                    [ ( "username", Arg.variable usernameVar )
                    , ( "password", Arg.variable passwordVar )
                    ]
                    (extract (field "token" [] string))
                )

Future plans for this package

There are a lot of things that this package can't do right now, but might do in the future. What gets done depends on how the package ends up being used, and how much demand there is for each feature. Here are some likely possibilities:

  • support for subscriptions
  • generating code from a GraphQL schemas and queries
  • providing functions to validate a query against a target schema
  • leveraging Relay-compliant schemas to cache response data and transform queries so that the client only asks the server for what it doesn't have already
  • providing an interface to implement a GraphQL schema that you can run queries against

Getting and giving help

If you're having trouble figuring out how to do something with this package, check out the #graphql channel on the Elm Slack — there are usually people there who can help. And if you can be one of those people who help other people, then thank you!

Running the tests

Install the elm-test npm package globally:

npm install -g elm-test

Make sure you have the latest version of elm-test, otherwise it may not be able to find the the test files in the right way. You can update an older version with npm update -g elm-test.

Now run elm-test in the root folder of this project:

elm-test
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].