Private
Package internals documentation.
Client
GraphQLClient.CLIENT — ConstantCLIENTRef which contains the global Client.
GraphQLClient._recursive_get_value — Method_recursive_get_value(dict, key)Recursively iterate through a dict until value of key is nothing.
GraphQLClient.introspect_node — Methodintrospect_node(node)Introspect single node in GQL schema.
Operations
GraphQLClient.generic_gql_query — Methodgeneric_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: iftrue, the query is formed by generating a string fromquery_argsdirectly, and the introspected schema is not used. Any ENUMs must be wrapped in aGQLEnum. Seedirectly_write_query_argsfor 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 totrueto throw an exception if the GraphQL server response contains errors that occurred during execution.verbose=0: set to 1, 2 for extra logging.
GraphQLClient.get_generic_query_payload — Functionget_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.
GraphQLClient.get_generic_query_payload_direct_write — Functionget_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.
GraphQLClient.clear_subscriptions — Methodclear_subscriptions()Removes all subscriptions from the subscription_tracker, throwing an error if any are still open.
GraphQLClient.readfromwebsocket — Methodreadfromwebsocket(ws::IO, stopfn, subtimeout)Read from the websocket with the following logic:
- If
stopfnis nothing andsubtimeoutis 0, usereadavailablewhich blocks data is written to the stream. - If
stopfnis not nothing, check the value ofstopfnperiodically. If it returns true, the websocket is closed. The period is set tosubtimeoutif greater than 0, otherwise 2 seconds is used. - If
stopfnis nothing butsubtimeout> 0, stop listening aftersubtimeoutseconds 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
GraphQLClient._execute — Method_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 TPrivate function to execute a HTTP Post request.
GraphQLClient.checkbodyforerrors — Methodcheckbodyforerrors(body::GQLResponse)If body has any errors, throw a GraphQLError.
GraphQLClient.handle_deserialisation_error — Methodhandle_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.
GraphQLClient.handle_error — Methodhandle_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.
GraphQLClient.GQLError — TypeGQLErrorStruct to contain information for errors recieved from the GraphQL server.
GraphQLClient.GQLLocation — TypeGQLLocationStruct to contain the location of GraphQL errors.
GraphQLClient.GQLSubscriptionResponse — TypeGQLSubscriptionResponse{T}Struct for subsriptions that wraps a GQLReponse{T} alongside various metadata.
GraphQLClient.get_name — Methodget_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.
Output Fields
GraphQLClient._get_field_str — Method_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 {}.
GraphQLClient.get_all_output_fields_str — Functionget_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.
GraphQLClient.get_field_names_string — Methodget_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.
GraphQLClient.get_output_str — Methodget_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_stris 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
}
}Arguments
GraphQLClient._get_val_str — Method_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
GraphQLClient.directly_write_query_args — Methoddirectly_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_enumGraphQLClient.get_query_args_str — Methodget_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
}
]
)GraphQLClient.initialise_arg_names — Methodinitialise_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" => ""GraphQLClient.is_field_name_used — Methodis_field_name_used(fieldname, fieldnamelist)True if fieldname is in fieldnamelist.
GraphQLClient.prettify_query — Methodprettify_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
)
}
]Variables
GraphQLClient.get_query_variables — Methodget_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]GraphQLClient.get_variables_str — Methodget_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 aAbstractDictorVector{<: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 ofarg_namesshould match that ofargs.query::String: query/mutation/subscription nametypedict=client.query_to_args_map: dictionary to look up type in. For top level variables,query_to_args_mapis used. For lower level variables,type_to_fields_mapis 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!,"Schema Utilities
GraphQLClient.GraphQLType — TypeAbstract type for GraphQL objects
GraphQLClient.InputObject — TypeInputObject type
GraphQLClient.Object — TypeObject type
GraphQLClient.get_field_type_string — Methodget_field_type_string(field)Returns string of the type of a GQL field by determining the kind of the field and acting accordingly.
GraphQLClient.getjuliatype — Methodgetjuliatype(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.
GraphQLClient.getroottype — Methodgetroottype(field)Get the name of the root type of a field.
GraphQLClient.getroottypefield — Methodgetroottypefield(field)Get the root type field of a NON_NULL or LIST field.
GraphQLClient.getsubfield — Methodgetsubfield(field)Return field["type"] or field["ofType"], throwing an error if neither exist.
GraphQLClient.isroottypeenum — Methodisroottypeenum(field)Return true if field is an arbitrarily nested enum (nested in both NON_NULL and/or LISTs).
GraphQLClient.isroottypeobject — Methodisroottypeobject(field)Return true if field is an arbitrarily nested enum (nested in both NON_NULL and/or LISTs).
GraphQLClient.isroottypescalar — Methodisroottypescalar(field)Return true if field is an arbitrarily nested scalr (nested in both NON_NULL and/or LISTs).
GraphQLClient.istype — Methodistype(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.
Type Introspection
GraphQLClient._instrospect_object — Method_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.
GraphQLClient.build_name_to_type — Methodbuild_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.
GraphQLClient.create_struct_AST — Methodcreate_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.
Logging
GraphQLClient.output_debug — Methodoutput_debug(verbose)Use to control whether or not a message should be printed that can be considered as a debug level message.
GraphQLClient.output_info — Methodoutput_info(verbose)Use to control whether or not a message should be printed that can be considered as a info level message.