Private

Package internals documentation.

Client

Operations

GraphQLClient.generic_gql_queryMethod
generic_gql_query(client::Client,
                  query_type::String,
                  query_name::Union{Alias, String},
                  query_args::Dict,
                  output_str::String="";
                  direct_write=false,
                  retries=1,
                  retry_non_idempotent=true)

Build and execute a query to client.

Arguments

  • client::Client: GraphQL client.
  • query_type::String,: typically "query", "mutation" or "subscription".
  • query_name::Union{Alias, AbstractString}: name of query.
  • query_args::Dict: dictionary of argument key value pairs - can be nested with dictionaries and lists.
  • output_str::String: output string to be appended to query.
  • direct_write=false: if true, the query is formed by generating a string from query_args directly, and the introspected schema is not used. Any ENUMs must be wrapped in a GQLEnum. See directly_write_query_args for more information.
  • output_type::Type=Any: output data type for query response object.
  • retries=1: number of times the mutation will be attempted before erroring.
  • readtimeout=0: HTTP request timeout length. Set to 0 for no timeout.
  • throw_on_execution_error=false: set to true to throw an exception if the GraphQL server response contains errors that occurred during execution.
  • verbose=0: set to 1, 2 for extra logging.
source
GraphQLClient.get_generic_query_payloadFunction
get_generic_query_payload(client::Client, query_type, query_name, query_args, output_str="")

Get the payload for a gql query.

Arguments

  • query_type: typically "query", "mutation" or "subscription".
  • query_name: name of query.
  • query_args: dictionary of argument key value pairs - can be nested with dictionaries and lists.
  • output_str: output string to be appended to query.
  • verbose=0: set to 1, 2 for extra logging.
source
GraphQLClient.get_generic_query_payload_direct_writeFunction
get_generic_query_payload_direct_write(query_type, query_name, query_args, output_str="")

Get the payload for a gql query, with the main body of the query being JSON3.write(query_args).

Arguments

  • query_type: typically "query", "mutation" or "subscription".
  • query_name: name of query.
  • query_args: dictionary of argument key value pairs - can be nested with dictionaries and lists.
  • output_str: output string to be appended to query.
  • verbose=0: set to 1, 2 for extra logging.
source
GraphQLClient.readfromwebsocketMethod
readfromwebsocket(ws::IO, stopfn, subtimeout)

Read from the websocket with the following logic:

  • If stopfn is nothing and subtimeout is 0, use readavailable which blocks data is written to the stream.
  • If stopfn is not nothing, check the value of stopfn periodically. If it returns true, the websocket is closed. The period is set to subtimeout if greater than 0, otherwise 2 seconds is used.
  • If stopfn is nothing but subtimeout > 0, stop listening after subtimeout seconds if no data has been received.

A channel is returned with the data. If stopfn stops the websocket, the data will be :stopfn. If the timeout stops the websocket, the data will be :timeout

source
GraphQLClient._executeMethod
_execute(endpoint::AbstractString,
         execution_string::AbstractString,
         headers::AbstractDict,
         output_type::Type{T}=Any;
         retries=1,
         readtimeout=0,
         throw_on_execution_error=false)::GQLResponse{T} where T

Private function to execute a HTTP Post request.

source
GraphQLClient.handle_deserialisation_errorMethod
handle_deserialisation_error(::Exception, _, _)
handle_deserialisation_error(err::HTTP.StatusError, resp, output_type)

Handle the error caught during deserialisation.

If it is an ArgumentError containing "invalid JSON" in its message, then we attempt to deserialise the body of the response using a GQLResponse{Any} object (if this wasn't the original output type). This is because this type can handle null fields in the response, whereas a user defined type may not.

Once deserialised, if there are errors in the body these are thrown. Otherwise, the original error is rethrown.

source
GraphQLClient.handle_errorMethod
handle_error(::Exception)
handle_error(err::HTTP.StatusError)

Handle the error caught during HTTP execution and deserialisation.

It the error is an HTTP.StatusError with status 400, a GraphQLError is thrown, otherwise the original error is thrown.

source
GraphQLClient.get_nameMethod
get_name(name::AbstractString)
get_name(alias::Alias)

To be used when the GraphQL field name is required, which will either be inputted as a string or in the name field of an Alias.

source

Output Fields

GraphQLClient._get_field_strMethod
_get_fields_str(client::Client, field, objects_that_recurse)

Returns a string containing all fields of the given field.

If field is not NON_NULL or an OBJECT, the name of the field is returned. Otherwise, the subfield(s) of the field are returned wrapped in {}.

source
GraphQLClient.get_all_output_fields_strFunction
get_all_output_fields_str(client::Client, query_name, objects_to_ignore=String[])

Returns a string containing all fields of the given query. To be used when returning all fields from a GQL query.

This could be used with mutations (untested), but the default mutation behaviour is to return nothing.

source
GraphQLClient.get_field_names_stringMethod
get_field_names_string(client::Client, query_name, objects_to_ignore, objects_that_recurse)

Returns a string containing all fields of the given GQL schema type.

Gets all fields from type_to_fields_map and then recursively gets all fields.

source
GraphQLClient.get_output_strMethod
get_output_str(outputs::Vector)
get_output_str(output::String)
get_output_str(output::Alias)
get_output_str(output::Dict)

Return a String containing the output fields. Options:

  • If input arg is a Vector, get_output_str is called on each element.
  • If input arg is a String, the input is returned with a comma added.
  • If input is an Alias, "$(Alias.alias):$(Alias.name)," is returned.
  • If input arg is a Dict, the output creates a structured output string based on the keys and values.

Examples

julia> str = get_output_str(["Field1", "Field2"])
"Field1,Field2,"
julia> println(prettify_query(str))
Field1
Field2

julia> str = get_output_str("Field1")
"Field1,"

julia> str = get_output_str(["OuterField", Dict("Outer" => Dict("Inner" => ["Field1", "Field2"]))])
"OuterField,Outer{Inner{Field1,Field2,},},"

julia> println(prettify_query(str))
OuterField
Outer{
    Inner{
        Field1
        Field2
    }
}
source

Arguments

GraphQLClient._get_val_strMethod
_get_val_str(val::String)
_get_val_str(val::Dict)
_get_val_str(val::Vector)
_get_val_str(enum::GQLEnum) 
_get_val_str(val)

Return value string for directly_write_query_args

source
GraphQLClient.directly_write_query_argsMethod
directly_write_query_args(query_args)

Returns a string which represents query_args by inserting values directly into the string. Strings are bracketed with " as this is required by GraphQL, but unfortunately this does not work for ENUMs as we cannot tell if a string is meant to be an enum or not without introspection. Therefore, any enums must be wrapped by a GQLEnum.

Examples

julia> query_args = Dict("string"=>"my_string", "dict"=>Dict("bool"=>true,"int"=>1), "vec"=>[Dict("float"=>1.0)])
Dict{String, Any} with 3 entries:
  "dict"   => Dict{String, Integer}("int"=>1, "bool"=>true)
  "string" => "my_string"
  "vec"    => [Dict("float"=>1.0)]

julia> println(prettify_query(directly_write_query_args(query_args)))
dict:{
    int:1
    bool:true
}
string:"my_string"
vec:[
    {
        float:1.0
    }
]

julia> query_args = Dict("string"=>"my_string", "enum" => GQLEnum("my_enum"))
Dict{String, Any} with 2 entries:
  "string" => "my_string"
  "enum"   => GQLEnum("my_enum")

julia> println(prettify_query(directly_write_query_args(query_args)))
string:"my_string"
enum:my_enum
source
GraphQLClient.get_query_args_strMethod
get_query_args_str(args::AbstractDict)

Get the mutation arguments string and a dictionary containing the argument names, which will not necessarily match the name of the types in the schema.

Uses an internal function to go through args dictionary, recursing down through the values that are AbstractDict or Vector{<:AbstractDict}, ensuring that no argument name is duplicated and enumerating multiple of the same type if in a vector.

Examples

julia> args = Dict("TopLevelVarA" => "value", "TopLevelVarB" => 2);

julia> str, arg_names = get_query_args_str(args);

julia> println(prettify_query(str))
(
    TopLevelVarA:$TopLevelVarA
    TopLevelVarB:$TopLevelVarB
)

julia> args = Dict("A" => "value", "B" => 2, "C" => Dict("D" => 3, "E" => 4));

julia> str, arg_names = get_query_args_str(args);

julia> print(prettify_query(str))
(
    B:$B
    A:$A
    C:{
        D:$D
        E:$E
    }
)

julia> args = Dict("A" => "value", "B" => 2, "C" => [Dict("D" => 3, "E" => 4), Dict("D" => 5, "E" => 6), Dict("D" => 7, "E" => 8)]);

julia> str, arg_names = get_query_args_str(args);

julia> print(prettify_query(str))
(
    B:$B
    A:$A
    C:[
        {
            D:$D1
            E:$E1
        }
        {
            D:$D2
            E:$E2
        }
        {
            D:$D3
            E:$E3
        }
    ]
)
source
GraphQLClient.initialise_arg_namesMethod
initialise_arg_names(args::Dict)

Recursively create arg_names Dict with same structure (dictionaries and vectors) and keys as args. Values are initialised as empty strings.

Examples

julia> args = Dict("int" => 1, "vector" => [1, 2, 3], "dict" => Dict("float" => 1.0), "vec_dict" => [Dict("bool" => true)])
Dict{String, Any} with 4 entries:
  "int"      => 1
  "dict"     => Dict("float"=>1.0)
  "vec_dict" => Dict{String, Bool}[Dict("bool"=>1)]
  "vector"   => [1, 2, 3]

julia> arg_names = initialise_arg_names(args)
Dict{String, Any} with 4 entries:
  "int"      => ""
  "dict"     => Dict{String, Any}("float"=>"")
  "vec_dict" => Dict{String, Any}[Dict("bool"=>"")]
  "vector"   => ""
source
GraphQLClient.prettify_queryMethod
prettify_query(str)

Prettifies a string, nesting for bracket types and adding new lines for commas.

Examples

julia> println(GraphQLClient.prettify_query("[{(a)}]"))
[
    {
        (
            a
        )
    }
]
julia> println(GraphQLClient.prettify_query("[{(a,b),(c,d)}]"))
[
    {
        (
            a
            b
        )
        (
            c
            d
        )
    }
]
source

Variables

GraphQLClient.get_query_variablesMethod
get_query_variables(args, arg_names)

Returns single level dictionary with variable name and value as key val pairs.

args and arg_names must be dictionaries with the same structure and keys. args contains the original variable name and its value, arg_names contains the original variable name and the name being used in the query, which may be different from the original variable name, for example if multiple of the same original name are used.

Examples

julia> args = Dict("int" => 1, "vector" => [1, 2, 3], "dict" => Dict("float" => 1.0), "vec_dict" => [Dict("bool" => true, "int" => 2)]);

julia> _, arg_names = get_query_args_str(args);

julia> arg_names
Dict{String, Any} with 4 entries:
  "int"      => "int"
  "dict"     => Dict{String, Any}("float"=>"float")
  "vec_dict" => Dict{String, Any}[Dict("int"=>"int__2", "bool"=>"bool__2")]
  "vector"   => "vector__1"

julia> get_query_variables(args, arg_names)
Dict{String, Any} with 5 entries:
  "int"       => 1
  "int__2"    => 2
  "bool__2"   => true
  "float"     => 1.0
  "vector__1" => [1, 2, 3]
source
GraphQLClient.get_variables_strMethod
get_variables_str(client::Client,
                  args::AbstractDict,
                  arg_names::AbstractDict,
                  query::String;
                  typedict=client.query_to_args_map)

Returns the variable string, not bracketed, for the args of a given query. For each variable, the string is:

$var_name: var_type

where var_name is specified in arg_names. This allows multiple args of the same type to be parameterised with different names. For queries and mutations, arg_names is calculated by get_query_args_str.

Arguments

  • client::Client: client.
  • args::AbstractDict: contains name of type and value of argument as key value pairs. For nested arguments, the value should be a AbstractDict or Vector{<:AbstractDict}). See examples below.
  • arg_names::AbstractDict: contains name of type and name to be used in variable string as key value pairs. The structure and keys of arg_names should match that of args.
  • query::String: query/mutation/subscription name
  • typedict=client.query_to_args_map: dictionary to look up type in. For top level variables, query_to_args_map is used. For lower level variables, type_to_fields_map is used.

Examples

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

julia> args = Dict("code" => "BR");

julia> arg_names = Dict("code" => "code1");

julia> str = get_variables_str(client, args, arg_names, "country")
"\$code1: ID!,"
source

Schema Utilities

GraphQLClient.getjuliatypeMethod
getjuliatype(field; level=:top, scalar_types::Dict{String, DataType}=GQL_DEFAULT_SCALAR_TO_JULIA_TYPE)

Returns type of a GraphQL field by determining the kind of the field and acting accordingly.

Arguments

  • field: introspected field dictionary.
  • scalar_types::Dict{String, DataType}=GQL_DEFAULT_SCALAR_TO_JULIA_TYPE: optional dictionary of scalar type name to Julia type which defaults to internal dictionary containing default scalars only.
source
GraphQLClient.istypeMethod
istype(field, comparison)

Checks whether kind of field (which has either type or ofType as a key) is comparison. Error if both type and ofType are not keys.

source

Type Introspection

GraphQLClient._instrospect_objectMethod
_instrospect_object(client,
                    object_name;
                    objects_being_introspected=String[],
                    parent_map=Dict{String, Type}(),
                    mutable=true,
                    allowed_level=2,
                    scalar_types=GQL_DEFAULT_SCALAR_TO_JULIA_TYPE)

Create a new type from instrospection of the object specified by object_name. The name of the tupe is calculated by gen_sym(string(object_name))

This is an internal method that is called recursively.

See also: introspect_object.

source
GraphQLClient.build_name_to_typeMethod
build_name_to_type(client,
                   object_name;
                   objects_being_introspected=String[],
                   allowed_level=2,
                   custom_scalar_types=GQL_DEFAULT_SCALAR_TO_JULIA_TYPE,
                   kwargs...)

Builds a dictionary of field name to Julia type for the given object.

source
GraphQLClient.create_struct_ASTMethod
create_struct_AST(struct_name::Symbol, parent_type, fields, mutable=true)

Returns an Expr which can be evaluated to create a struct. The struct has fields and types specifed by the key value pairs of fields, with all types being a union of Nothing and the type supplied. If the parent_type method is used the struct is given the supplied parent type. Mutability can be controlled with the mutable kwarg.

source

Logging

GraphQLClient.output_debugMethod
output_debug(verbose)

Use to control whether or not a message should be printed that can be considered as a debug level message.

source
GraphQLClient.output_infoMethod
output_info(verbose)

Use to control whether or not a message should be printed that can be considered as a info level message.

source