AshOaskit. SpecModifier
(AshOasKit v0.2.0)
View Source
Provides support for modifying OpenAPI specifications after generation.
This module enables users to customize the generated OpenAPI spec through
callback functions, similar to AshJsonApi's modify_open_api option.
This is useful for adding custom extensions, modifying schemas, or
integrating with external documentation systems.
Modification Patterns
Function Callback
Pass a function that receives the spec and returns a modified spec:
AshOaskit.spec_31(
domains: [MyApp.Blog],
modify_open_api: fn spec ->
put_in(spec, ["info", "x-custom"], "value")
end
)MFA Tuple
Pass a module, function, args tuple for more complex modifications:
AshOaskit.spec_31(
domains: [MyApp.Blog],
modify_open_api: {MyApp.OpenApiCustomizer, :customize, [extra_arg]}
)Multiple Modifiers
Chain multiple modifications:
AshOaskit.spec_31(
domains: [MyApp.Blog],
modify_open_api: [
&add_custom_headers/1,
&add_rate_limiting_info/1,
{MyApp.Docs, :add_examples, []}
]
)Common Modifications
- Adding custom headers to all operations
- Adding x-* extension fields
- Modifying security schemes
- Adding webhook definitions
- Customizing server URLs per environment
- Adding examples to schemas
Summary
Functions
Adds a custom extension field to the spec at the specified path.
Adds external documentation link to the spec.
Adds custom headers to all operations in the spec.
Adds an example to an operation.
Adds a parameter definition to the components section.
Adds a response definition to the components section.
Adds or updates a schema in the components section.
Adds examples to a schema in the components section.
Adds a server to the spec's servers list.
Adds a tag to the spec's tags list.
Adds a webhook definition to the spec.
Applies modifications to an OpenAPI specification.
Creates a modifier function that adds deprecation notices to operations.
Creates a modifier function that adds rate limiting information.
Replaces the servers list in the spec.
Modifies the info section of the spec.
Types
Functions
Adds a custom extension field to the spec at the specified path.
Extension fields in OpenAPI start with "x-" and can contain any value.
Examples
iex> spec = %{"info" => %{"title" => "API"}}
...> AshOaskit.SpecModifier.add_extension(spec, ["info"], "x-logo", %{"url" => "logo.png"})
%{"info" => %{"title" => "API", "x-logo" => %{"url" => "logo.png"}}}
Adds external documentation link to the spec.
Examples
iex> spec = %{"info" => %{"title" => "API"}}
...>
...> AshOaskit.SpecModifier.add_external_docs(spec, "https://docs.example.com",
...> description: "Full documentation"
...> )
%{
"info" => %{"title" => "API"},
"externalDocs" => %{
"url" => "https://docs.example.com",
"description" => "Full documentation"
}
}
Adds custom headers to all operations in the spec.
This is useful for documenting common headers like correlation IDs, API versions, or custom authentication headers.
Options
:operations- List of operation IDs to modify. If nil, modifies all operations.:required- Whether the header is required. Defaults to false.
Examples
iex> spec = %{"paths" => %{"/posts" => %{"get" => %{"operationId" => "listPosts"}}}}
...>
...> AshOaskit.SpecModifier.add_header_to_operations(spec, "X-Request-ID", %{
...> "type" => "string",
...> "format" => "uuid"
...> })
Adds an example to an operation.
Examples
iex> spec = %{"paths" => %{"/posts" => %{"get" => %{"operationId" => "listPosts"}}}}
...> example = %{"summary" => "List posts", "value" => %{"data" => []}}
...>
...> AshOaskit.SpecModifier.add_operation_example(
...> spec,
...> "listPosts",
...> "application/json",
...> example
...> )
Adds a parameter definition to the components section.
Examples
iex> spec = %{"components" => %{}}
...> param = %{"name" => "page", "in" => "query", "schema" => %{"type" => "integer"}}
...> AshOaskit.SpecModifier.add_parameter(spec, "PageParam", param)
Adds a response definition to the components section.
Examples
iex> spec = %{"components" => %{}}
...> response = %{"description" => "Rate limit exceeded"}
...> AshOaskit.SpecModifier.add_response(spec, "RateLimitError", response)
Adds or updates a schema in the components section.
Examples
iex> spec = %{"components" => %{"schemas" => %{}}}
...> schema = %{"type" => "object", "properties" => %{"id" => %{"type" => "string"}}}
...> AshOaskit.SpecModifier.add_schema(spec, "CustomResource", schema)
%{"components" => %{"schemas" => %{"CustomResource" => %{...}}}}
Adds examples to a schema in the components section.
Examples
iex> spec = %{"components" => %{"schemas" => %{"Post" => %{"type" => "object"}}}}
...> examples = [%{"id" => "1", "title" => "Hello World"}]
...> AshOaskit.SpecModifier.add_schema_examples(spec, "Post", examples)
Adds a server to the spec's servers list.
Examples
iex> spec = %{"servers" => [%{"url" => "https://api.example.com"}]}
...>
...> AshOaskit.SpecModifier.add_server(spec, "https://staging.example.com",
...> description: "Staging"
...> )
%{
"servers" => [
%{"url" => "https://api.example.com"},
%{"url" => "https://staging.example.com", "description" => "Staging"}
]
}
Adds a tag to the spec's tags list.
Tags are used to group operations in documentation tools.
Examples
iex> spec = %{"tags" => [%{"name" => "Posts"}]}
...> AshOaskit.SpecModifier.add_tag(spec, "Comments", description: "Comment operations")
%{
"tags" => [
%{"name" => "Posts"},
%{"name" => "Comments", "description" => "Comment operations"}
]
}
Adds a webhook definition to the spec.
Webhooks are callbacks that the API can send to client-specified URLs.
Examples
iex> spec = %{}
...>
...> webhook = %{
...> "post" => %{
...> "summary" => "New post created",
...> "requestBody" => %{...}
...> }
...> }
...>
...> AshOaskit.SpecModifier.add_webhook(spec, "newPost", webhook)
Applies modifications to an OpenAPI specification.
The modifier can be:
- A function that takes the spec and returns the modified spec
- An MFA tuple
{module, function, args}where the spec is prepended to args - A list of modifiers to apply in sequence
Examples
iex> spec = %{"info" => %{"title" => "My API"}}
...>
...> AshOaskit.SpecModifier.apply_modifier(spec, fn s ->
...> put_in(s, ["info", "version"], "2.0")
...> end)
%{"info" => %{"title" => "My API", "version" => "2.0"}}
iex> spec = %{"info" => %{}}
...> AshOaskit.SpecModifier.apply_modifier(spec, {Map, :put, ["info", %{"title" => "New"}]})
%{"info" => %{"title" => "New"}}
Creates a modifier function that adds deprecation notices to operations.
Examples
iex> modifier =
...> AshOaskit.SpecModifier.deprecation_modifier(
...> operations: ["oldGetPosts"],
...> message: "Use listPosts instead",
...> sunset: "2024-12-31"
...> )
Creates a modifier function that adds rate limiting information.
This is a convenience function that creates a modifier for common rate limiting documentation patterns.
Options
:limit- Rate limit value (e.g., 100):window- Time window (e.g., "1 minute"):headers- Custom header names for rate limit info
Examples
iex> modifier = AshOaskit.SpecModifier.rate_limiting_modifier(limit: 100, window: "1 minute")
...> spec = %{"paths" => %{"/posts" => %{"get" => %{}}}}
...> AshOaskit.SpecModifier.apply_modifier(spec, modifier)
Replaces the servers list in the spec.
Useful for environment-specific server configuration.
Examples
iex> spec = %{"servers" => [%{"url" => "/"}]}
...> servers = [%{"url" => "https://api.prod.example.com"}]
...> AshOaskit.SpecModifier.set_servers(spec, servers)
%{"servers" => [%{"url" => "https://api.prod.example.com"}]}
Modifies the info section of the spec.
Examples
iex> spec = %{"info" => %{"title" => "API", "version" => "1.0"}}
...>
...> AshOaskit.SpecModifier.update_info(spec, %{
...> "contact" => %{"email" => "support@example.com"},
...> "license" => %{"name" => "MIT"}
...> })