GraphQLClient.jl

A Julia GraphQL client for seamless integration with a server
Popularity
48 Stars
Updated Last
4 Months Ago
Started In
October 2021

GraphQLClient.jl

A Julia GraphQL client for seamless integration with a server

Stable Stable Build Status Codecov ColPrac: Contributor's Guide on Collaborative Practices for Community Packages

This package is intended to make connecting to and communicating with GraphQL servers easy whilst integrating easily with the wider Julia ecosystem.

Key Features

  • Querying, mutating and subscribing without manual writing of query strings
  • @gql_str non-standard string literal which which validates a query string at compile time
  • Deserializing responses directly using StructTypes
  • Type stable querying
  • Construction of Julia types from GraphQL objects
  • Using introspection to help with querying

Installation

The package can be installed with Julia's package manager, either by using the Pkg REPL mode (press ] to enter):

pkg> add GraphQLClient

or by using Pkg functions

julia> using Pkg; Pkg.add("GraphQLClient")

Basic Usage

Connecting to a server

A client can be instantiated by using the Client type

using GraphQLClient

client = Client("https://countries.trevorblades.com")

This will, by default, use a query to introspect the server schema.

We can also set a global client to be used by queries, mutations, subscriptions and introspection functions.

global_graphql_client(Client("https://countries.trevorblades.com"))

Querying

We can query a client without having to type a full GraphQL query by hand, with the response containing fields obtained by introspection

response = query(client, "countries")

Or we can query the global client

response = query("countries")

We can add arguments and specify fields in the response

query_args = Dict("filter" => Dict("code" => Dict("eq" => "AU")))
response = query("countries"; query_args=query_args, output_fields="name");
response.data["countries"]
# 1-element Vector{Any}:
#  Dict{String, Any}("name" => "Australia")

Or we can query with the query string directly using either a normal String or the gql non-standard string literal which also performs some validation of the string:

query_string = gql"""
    query(
      $eq: String
    ){
    countries(
        filter:{
            code:{
                eq:$eq
            }
        }
    ){
        name
    }
}
"""

variables = Dict("eq" => "AU")

response = GraphQLClient.execute(query_string, variables=variables)

We can define a StructType to deserialise the result into

using StructTypes

struct CountryName
    name::String
end
StructTypes.StructType(::Type{CountryName}) = StructTypes.OrderedStruct()

response = query("countries", Vector{CountryName}, query_args=query_args, output_fields="name")

response.data["countries"][1]
# CountryName("Australia")

Or we can use introspection to build the type automatically

Country = GraphQLClient.introspect_object("Country")

response = query("countries", Vector{Country}, query_args=query_args, output_fields="name")

response.data["countries"][1]
# Country
#   name : Australia

Mutations

Mutations can be constructed in a similar way, except the arguments are not a keyword argument as typically a mutation is doing something with an input. For example

response = mutate(client, "mutation_name", Dict("new_id" => 1))
response = mutate("mutation_name", Dict("new_id" => 1)) # Use global client

Subscriptions

The subscriptions syntax is similar, except that we use Julia's do notation

open_subscription(
    client,
    "subscription_name",
    sub_args=("id" => 1),
    output_fields="val"
) do response
    val = response.data["subscription_name"]["val"]
    stop_sub = val == 2
    return stop_sub # If this is true, the subscription ends
end

Used By Packages