Private
Package internals documentation.
Client
GraphQLClient.CLIENT
— ConstantCLIENT
Ref
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_args
directly, and the introspected schema is not used. Any ENUMs must be wrapped in aGQLEnum
. Seedirectly_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 totrue
to 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
stopfn
is nothing andsubtimeout
is 0, usereadavailable
which blocks data is written to the stream. - If
stopfn
is not nothing, check the value ofstopfn
periodically. If it returns true, the websocket is closed. The period is set tosubtimeout
if greater than 0, otherwise 2 seconds is used. - If
stopfn
is nothing butsubtimeout
> 0, stop listening aftersubtimeout
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
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 T
Private 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
— TypeGQLError
Struct to contain information for errors recieved from the GraphQL server.
GraphQLClient.GQLLocation
— TypeGQLLocation
Struct 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_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
}
}
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_enum
GraphQLClient.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 aAbstractDict
orVector{<: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_names
should 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_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!,"
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.