GraphqlQuery.Schema.Remote (graphql_query v0.6.2)
View SourceUtilities for managing remote GraphQL schemas.
Provides functions for deriving schema file paths from module names, resolving schema directory configuration, discovering remote schema modules, fetching remote schema content, and managing schema files on disk.
Configuration
The schemas directory can be configured at multiple levels (in order of precedence):
- Per-module
:schemas_diroption inuse GraphqlQuery.Schema - Application config:
config :graphql_query, schemas_dir: "priv/graphql/schemas" - Default:
"priv/graphql/schemas"
File Path Derivation
Module names are converted to underscored/nested file paths:
MyApp.ExternalSchema→<schemas_dir>/my_app/external_schema.graphqlMyApp.GitHub.Schema→<schemas_dir>/my_app/git_hub/schema.graphql
Summary
Functions
Builds the schema/0 function AST for a remote schema module.
Generates the quoted AST block for a remote schema module.
Returns the default schemas directory path.
Derives a schema file path from a module name and schemas directory.
Discovers all compiled modules that have remote schema configuration.
Fetches the SDL content for a remote schema.
Returns remote schema information for a specific module.
Resolves the schema file path and schemas directory for a remote module.
Resolves the schemas directory from the given option, application config, or default.
Resolves a remote URL at runtime.
Saves schema content to the given file path, creating directories as needed.
Checks whether the stored schema file matches the given content.
Checks whether a URL value is valid for the :remote :url option.
Validates the :remote configuration keyword list.
Emits a compile-time warning when a remote schema file does not exist locally.
Functions
Builds the schema/0 function AST for a remote schema module.
When the local schema file exists at compile time, generates a function that
loads it via gql_from_file/2. When it does not exist, generates a function
that raises GraphqlQuery.Schema.RemoteNotFetchedError.
Generates the quoted AST block for a remote schema module.
Called by GraphqlQuery.Schema.__using__/1 when the :remote option is
present. Validates the remote configuration, resolves file paths, warns if
the local schema file is missing, and returns a quoted block that defines
__remote_config__/0, __schemas_dir__/0, build_request/1, schema/0,
and schema_path/0 on the caller module.
Parameters
remote— the keyword list passed as the:remoteoptionschemas_dir_opt— the optional:schemas_diroverride (ornil)module— the caller module atom (__CALLER__.module)explicit_path— an explicit:schema_pathvalue (ornil)
@spec default_schemas_dir() :: String.t()
Returns the default schemas directory path.
Derives a schema file path from a module name and schemas directory.
Converts the module name to an underscored/nested path structure with a .graphql extension.
Examples
iex> GraphqlQuery.Schema.Remote.derive_schema_path(MyApp.ExternalSchema, "priv/graphql/schemas")
"priv/graphql/schemas/my_app/external_schema.graphql"
iex> GraphqlQuery.Schema.Remote.derive_schema_path(MyApp.GitHub.Schema, "priv/schemas")
"priv/schemas/my_app/git_hub/schema.graphql"
@spec discover_remote_schemas() :: [map()]
Discovers all compiled modules that have remote schema configuration.
Scans all loaded applications and their modules for those that export
a __remote_config__/0 function, indicating they have remote schema setup.
Returns a list of maps with module info including the module, remote config, schemas directory, and derived file path.
Examples
iex> GraphqlQuery.Schema.Remote.discover_remote_schemas()
[
%{
module: MyApp.ExternalSchema,
remote: [url: "https://api.example.com/schema.graphql"],
schemas_dir: "priv/graphql/schemas",
schema_path: "priv/graphql/schemas/my_app/external_schema.graphql"
}
]
Fetches the SDL content for a remote schema.
Accepts the info map produced by module_remote_info/1 (or discover_remote_schemas/0).
Resolves the URL at runtime (supporting both plain strings and {Module, :function} tuples),
selects the correct HTTP strategy based on :mode, and delegates to the module's
build_request/1 callback for request customisation.
Returns {:ok, sdl} on success or {:error, reason} on failure.
Examples
iex> info = GraphqlQuery.Schema.Remote.module_remote_info(MyApp.ExternalSchema)
iex> GraphqlQuery.Schema.Remote.fetch_schema(info)
{:ok, "type Query { ... }"}
Returns remote schema information for a specific module.
Examples
iex> GraphqlQuery.Schema.Remote.module_remote_info(MyApp.ExternalSchema)
%{
module: MyApp.ExternalSchema,
remote: [url: "https://api.example.com/schema.graphql"],
schemas_dir: "priv/graphql/schemas",
schema_path: "priv/graphql/schemas/my_app/external_schema.graphql"
}
@spec resolve_schema_paths(String.t() | nil, String.t() | nil, module()) :: {String.t(), String.t() | nil}
Resolves the schema file path and schemas directory for a remote module.
When explicit_path is provided, it is used directly and schemas_dir is
nil. Otherwise, the path is derived from the module name using
derive_schema_path/2 and the resolved schemas directory.
Returns a {schema_path, schemas_dir} tuple.
Resolves the schemas directory from the given option, application config, or default.
Resolution Order
- The
module_optvalue if notnil - Application config:
config :graphql_query, schemas_dir: "..." - Default:
"priv/graphql/schemas"
Examples
iex> GraphqlQuery.Schema.Remote.resolve_schemas_dir("custom/path")
"custom/path"
iex> GraphqlQuery.Schema.Remote.resolve_schemas_dir(nil)
"priv/graphql/schemas"
Resolves a remote URL at runtime.
Accepts either a plain string URL or a {Module, :function} tuple. When a
tuple is given the function is called with no arguments and its return value
(which must be a non-empty string) is used as the URL.
Examples
iex> GraphqlQuery.Schema.Remote.resolve_url("https://example.com/schema.graphql")
"https://example.com/schema.graphql"
iex> GraphqlQuery.Schema.Remote.resolve_url({Module, :url})
# calls Module.url() at runtime
Saves schema content to the given file path, creating directories as needed.
Examples
iex> GraphqlQuery.Schema.Remote.save_schema("/tmp/test_schema.graphql", "type Query { hello: String }")
:ok
Checks whether the stored schema file matches the given content.
Returns true if the file exists and its content matches exactly,
false otherwise (including when the file doesn't exist).
Examples
iex> File.write!("/tmp/test_match.graphql", "type Query { hello: String }")
iex> GraphqlQuery.Schema.Remote.schemas_match?("/tmp/test_match.graphql", "type Query { hello: String }")
true
iex> GraphqlQuery.Schema.Remote.schemas_match?("/tmp/nonexistent.graphql", "content")
false
Checks whether a URL value is valid for the :remote :url option.
Accepts non-empty binary strings and {Module, :function} tuples.
@spec validate_config!(keyword()) :: :ok
Validates the :remote configuration keyword list.
Raises CompileError when:
- the value is not a keyword list
- the
:urlkey is missing - unknown keys are present (valid keys:
[:url, :mode]) - the
:urlvalue is not a non-empty string or{Module, :function}tuple - the
:modevalue is not one of[:fetch, :introspect]
Emits a compile-time warning when a remote schema file does not exist locally.
Called during compilation to alert developers that the schema needs to be
fetched with mix graphql_query.schema.fetch.