@spec primary_graph(schema()) :: DCATR.DataGraph.t() | nil
Default implementation of primary_graph/1.
Delegates to the repository's DCATR.Repository.Type.primary_graph/1.
Behaviour for service types that provide operations for repository access and processing.
This behaviour enables applications to create specialized DCATR.Service types with custom operations,
APIs, and data processing workflows. See DCATR.Service for the foundational service model.
Service types define the infrastructure for implementing operations that access repository data. The callbacks provided by this behaviour handle loading, graph management, and name resolution - all in service of enabling operation implementations.
Each service aggregates data from two catalogs:
Loading callbacks:
load_from_dataset/3 - Initialize service from RDF manifest dataload_graph_names/2 - Extract graph name mappings from manifestGraph name callbacks (infrastructure for triple-store operations):
graph_name/3 - Translate graph references to local storage namesgraph_by_name/2 - Retrieve graphs via local namesdefault_graph/1 - Access the designated default graphprimary_graph/1 - Access the primary graph from the repositoryInherits from DCATR.GraphResolver:
DCATR.GraphResolver.resolve_graph_selector/2 — delegates across repository and local_dataGraph names enable triple-store operations by mapping global graph IDs to service-local storage names. Names can be:
dcatr:localGraphName):default (via dcatr:DefaultGraph)Custom service types should use DCATR.Service.Type and define a Grax schema
extending DCATR.Service:
defmodule MyApp.Service do
use DCATR.Service.Type
schema MyApp.NS.Service < DCATR.Service do
end
# Define service-specific operations
def query(service, sparql) do
# Use graph/2, graph_name/3 to implement operations
...
end
endThe module automatically provides delegating implementations of all callbacks, convenience functions for type introspection, and helper functions for graph name management. All generated functions are overridable.
Returns the default graph if one is designated.
Returns a graph by its local name.
Returns the graph name for a given graph, selector, or ID.
Loads a service from a dataset.
Loads graph name mappings from a service manifest graph.
Returns the primary graph from the repository if one is designated.
Returns the effective value of use_primary_as_default for this service.
Adds a graph name mapping to the service.
Default implementation of default_graph/1.
Default implementation of graph/2.
Default implementation of graph_by_id/2.
Default implementation of graph_by_name/2.
Default implementation of graph_name/3.
Default implementation for graph_name_mapping/1.
Default implementation of graphs/1.
Default implementation of load_from_dataset/3.
Default implementation of load_graph_names/2.
Default implementation of primary_graph/1.
Returns the repository type module for a given service type.
Default implementation of DCATR.GraphResolver.resolve_graph_selector/2.
Returns the service data type module for a given service type.
Default implementation of use_primary_as_default/1.
@type coercible_graph_name() :: DCATR.Service.graph_name() | RDF.IRI.coercible()
@type schema() :: Grax.Schema.t()
@type t() :: module()
@callback default_graph(service :: schema()) :: DCATR.Graph.t() | nil
Returns the default graph if one is designated.
Override to customize default graph selection.
@callback graph_by_name(service :: schema(), coercible_graph_name()) :: DCATR.Graph.t() | nil
Returns a graph by its local name.
This callback enables lookups via service-specific local names.
Override to customize name resolution logic.
@callback graph_name( service :: schema(), selector_or_graph_or_id :: atom() | DCATR.Graph.t() | RDF.IRI.coercible(), opts :: keyword() ) :: DCATR.Service.graph_name() | nil
Returns the graph name for a given graph, selector, or ID.
This callback provides the critical graph-name translation API for triple-store access (e.g., Gno), where operations require the local graph name under which a graph is stored.
Called by client code that needs to translate graph references into their local storage names for triple-store operations, SPARQL queries, or graph management commands.
Override to customize graph name resolution (e.g., dynamic name generation, store-specific naming conventions).
:strict - When true (default), verifies graph existence before returning the ID;
when false, returns the ID without existence check@callback load_from_dataset( dataset :: RDF.Dataset.t(), service_id :: RDF.IRI.coercible(), opts :: keyword() ) :: {:ok, schema()} | {:error, any()}
Loads a service from a dataset.
This callback enables service initialization from RDF manifest data, supporting environment-specific configuration and manifest-based bootstrapping.
Called by DCATR.Manifest.Loader.load_manifest/2 during manifest loading to
construct the complete service hierarchy (Service → Repository → Dataset).
Override to customize service loading logic (e.g., loading additional linked resources, applying environment-specific transformations).
@callback load_graph_names(service :: schema(), graph :: RDF.Graph.t()) :: {:ok, schema()} | {:error, Exception.t()}
Loads graph name mappings from a service manifest graph.
This callback extracts local graph name assignments from RDF manifest data, populating
the service's graph_names mapping.
Usually called by load_from_dataset/3 after the service and repository are loaded.
Override to customize graph name extraction (e.g., additional naming schemes, validation).
@callback primary_graph(service :: schema()) :: DCATR.DataGraph.t() | nil
Returns the primary graph from the repository if one is designated.
Override to customize primary graph selection.
Returns the effective value of use_primary_as_default for this service.
Resolves the three-value semantics:
true, false, or nil)nil)Override to customize the resolution logic (e.g., different configuration source).
@spec add_graph_name(schema(), coercible_graph_name(), coercible_graph_name()) :: {:ok, schema()} | {:error, Exception.t()}
Adds a graph name mapping to the service.
Validates graph existence and ensures name uniqueness before updating both
graph_names (name→ID) and graph_names_by_id (ID→name) mappings of DCATR.Service.
@spec default_graph(schema()) :: DCATR.Graph.t() | nil
Default implementation of default_graph/1.
Returns the graph mapped to the :default local name via graph_by_name/2.
@spec graph(schema(), DCATR.GraphResolver.id_or_selector()) :: DCATR.Graph.t() | nil
Default implementation of graph/2.
Tries selector resolution, then local name lookup, then ID lookup across Repository and ServiceData catalogs.
@spec graph_by_id(schema(), RDF.IRI.coercible()) :: DCATR.Graph.t() | nil
Default implementation of graph_by_id/2.
Searches in Repository and ServiceData catalogs.
@spec graph_by_name(schema(), coercible_graph_name()) :: DCATR.Graph.t() | nil
Default implementation of graph_by_name/2.
Looks up the graph ID in graph_names mapping, then delegates to graph_by_id/2.
@spec graph_name( schema(), DCATR.GraphResolver.selector() | DCATR.Graph.t() | RDF.IRI.coercible(), keyword() ) :: DCATR.Service.graph_name() | nil
Default implementation of graph_name/3.
Resolves selectors via graph/2 and looks up local name mappings in graph_names_by_id.
Returns nil if the graph does not exist (when strict: true).
:strict - When true (default), checks graph existence before returning
the ID as a fallback. When false, returns the provided graph ID directly
without existence check.@spec graph_name_mapping(schema()) :: DCATR.Service.graph_names()
Default implementation for graph_name_mapping/1.
Returns the graph_names map from the DCATR.Service struct.
@spec graphs(schema()) :: [DCATR.Graph.t()]
Default implementation of graphs/1.
Aggregates all graphs from Repository and ServiceData catalogs.
@spec load_from_dataset(t(), RDF.Dataset.t(), RDF.IRI.coercible(), keyword()) :: {:ok, schema()} | {:error, any()}
Default implementation of load_from_dataset/3.
Loads service and repository from their manifest graphs in two stages from the
different manifest graphs, then enriches the service with graph name mappings
from the service manifest via load_graph_names/2.
@spec load_graph_names(schema(), RDF.Graph.t()) :: {:ok, schema()} | {:error, any()}
Default implementation of load_graph_names/2.
Extracts dcatr:localGraphName statements and dcatr:DefaultGraph type assertions
from the given graph, populating graph_names and graph_names_by_id maps of DCATR.Service.
After extracting explicit graph name mappings, applies automatic primary-as-default designation
based on the service's use_primary_as_default setting.
@spec primary_graph(schema()) :: DCATR.DataGraph.t() | nil
Default implementation of primary_graph/1.
Delegates to the repository's DCATR.Repository.Type.primary_graph/1.
Returns the repository type module for a given service type.
Extracts the DCATR.Repository.Type from the service's :repository property schema definition.
iex> DCATR.Service.Type.repository_type(DCATR.Service)
DCATR.Repository
@spec resolve_graph_selector(schema(), DCATR.GraphResolver.selector()) :: DCATR.Graph.t() | nil | :undefined
Default implementation of DCATR.GraphResolver.resolve_graph_selector/2.
Resolves :default selector at service level, then delegates to Repository and ServiceData catalogs.
Returns the service data type module for a given service type.
Extracts the DCATR.ServiceData.Type from the service's :local_data property schema definition.
iex> DCATR.Service.Type.service_data_type(DCATR.Service)
DCATR.ServiceData
Default implementation of use_primary_as_default/1.
Resolves the three-value semantics:
When set in manifest: returns the manifest value (true, false, or nil)
When not set in manifest: returns application config value (defaults to nil), which can
be configured like this
config :dcatr, :use_primary_as_default, true # Enforce mode