AshOaskit. SchemaBuilder. RelationshipSchemas
(AshOasKit v0.2.0)
View Source
Relationship schema building for JSON:API responses.
This module handles the generation of OpenAPI schemas for Ash resource relationships. JSON:API relationships include resource linkage (id/type) and optional links for navigation.
Overview
In JSON:API, relationships are represented with:
- data - Resource identifier(s) containing
idandtype - links - Optional
selfandrelatedURLs for navigation
Cardinality Handling
The schema structure differs based on relationship cardinality:
| Relationship Type | Cardinality | Schema |
|---|---|---|
belongs_to | :one | Single identifier (nullable) |
has_one | :one | Single identifier (nullable) |
has_many | :many | Array of identifiers |
many_to_many | :many | Array of identifiers |
Nullable Handling by Version
For to-one relationships, null values are handled differently by version:
- OpenAPI 3.0: Uses
"nullable": trueon the identifier schema - OpenAPI 3.1: Uses
oneOfwith the identifier and{"type": "null"}
Cycle Detection
When building relationship schemas, the module checks if the destination resource has been seen. If not, it triggers schema generation for that resource to ensure all referenced schemas exist in the spec.
Usage
# Build a relationship schema
{schema, builder} = RelationshipSchemas.build_relationship_schema(builder, rel)
# Add all relationships for a resource
builder = RelationshipSchemas.add_relationships_schema(builder, resource, "Post")
Summary
Functions
Adds the relationships schema for a resource if it has any.
Builds a relationship schema with data and links.
Gets the JSON:API type for a resource.
Gets public relationships for a resource.
Checks if a resource has any public relationships.
Determines if a relationship is to-many or to-one.
Functions
Adds the relationships schema for a resource if it has any.
Creates a schema containing all public relationships with their data (resource linkage) and links properties.
Parameters
builder- The SchemaBuilder accumulatorresource- The Ash resource moduleschema_name- Base name for the schemaadd_schema_fn- Function to add schemas to builder
Returns
Updated builder with relationships schema added (if resource has relationships).
Builds a relationship schema with data and links.
Creates a JSON:API compliant relationship object schema that includes the resource linkage (data) and navigation links.
Parameters
builder- The SchemaBuilder accumulatorrelationship- The relationship struct from Ash.Resource.Info
Returns
A tuple of {relationship_schema, updated_builder}.
Example Output
For a to-many relationship:
{
%{
"type" => "object",
"properties" => %{
"data" => %{
"type" => "array",
"items" => %{
"type" => "object",
"properties" => %{
"id" => %{"type" => "string"},
"type" => %{"type" => "string", "enum" => ["posts"]}
},
"required" => ["id", "type"]
}
},
"links" => %{...}
}
},
builder
}
Gets the JSON:API type for a resource.
Uses the configured type from AshJsonApi if available, otherwise derives from the module name.
Parameters
resource- The Ash resource module
Returns
The JSON:API type string.
Examples
iex> RelationshipSchemas.get_json_api_type(MyApp.BlogPost)
# From AshJsonApi config or derived from module name
"blog_posts"
Gets public relationships for a resource.
Only relationships marked public? true are included.
Parameters
resource- The Ash resource module
Returns
List of public relationship structs.
Checks if a resource has any public relationships.
Parameters
resource- The Ash resource module
Returns
true if the resource has relationships, false otherwise.
@spec relationship_cardinality(map()) :: :one | :many
Determines if a relationship is to-many or to-one.
Checks the cardinality field first (Ash 3.x), falling back to
relationship type for compatibility.
Parameters
rel- The relationship struct
Returns
:one or :many.
Examples
iex> RelationshipSchemas.relationship_cardinality(%{cardinality: :many})
:many
iex> RelationshipSchemas.relationship_cardinality(%{type: :belongs_to})
:one