spectra_openapi (spectra v0.17.0)
View SourceSummary
Functions
Adds a complete response specification to an endpoint.
Creates a basic endpoint specification.
Creates an endpoint specification with documentation.
Generates a complete OpenAPI 3.1 specification from a list of endpoints.
Formats the badarg errors raised by with_nil_fields/2 and to_openapi/4.
Called by erl_error and by Elixir to build the error message.
Creates a response builder for constructing response specifications.
Adds a response body to a response builder.
Adds a response body with custom content type to a response builder.
Adds a header to a response builder.
Generates a complete OpenAPI 3.1 specification from endpoints and webhooks.
Creates a webhook specification.
Creates a webhook specification with documentation.
Makes the webhook payload write every missing value as null.
Adds a parameter specification to an endpoint.
Adds a request body to an endpoint.
Adds a request body to an endpoint with a custom content type.
Types
-type endpoint_spec() :: #{method := http_method(), path := binary(), responses := #{http_status_code() => response_spec()}, parameters := [parameter_spec()], request_body => request_body_spec(), doc => endpoint_doc()}.
-type http_method() :: get | put | post | delete | options | head | patch | trace.
-type http_status_code() :: 100..599 | <<_:24>>.
-type openapi_header() :: #{description => binary(), required => boolean(), deprecated => boolean(), schema := openapi_schema()}.
-type openapi_metadata() :: #{title := binary(), version := binary(), summary => binary(), description => binary(), terms_of_service => binary(), contact => openapi_contact(), license => openapi_license(), servers => [openapi_server()], security_schemes => #{binary() => openapi_security_scheme()}, security => [openapi_security_requirement()]}.
-type openapi_operation() :: #{summary => binary(), description => binary(), operationId => binary(), tags => [binary()], deprecated => boolean(), externalDocs => #{description => binary(), url := binary()}, security => [openapi_security_requirement()], responses => #{binary() => openapi_response()}, requestBody => openapi_request_body(), parameters => [openapi_parameter()]}.
-type openapi_parameter() :: #{name := binary(), in := parameter_location(), required := boolean(), schema := openapi_schema(), description => binary(), deprecated => boolean()}.
-type openapi_request_body() :: #{required := boolean(), content := #{binary() => #{schema := openapi_schema()}}, description => binary()}.
-type openapi_response() :: #{description := binary(), content => #{binary() => #{schema := openapi_schema()}}, headers => #{binary() => openapi_header()}}.
-type openapi_schema() :: json:encode_value() | #{'$ref' := binary()}.
-type openapi_security_scheme() :: json:encode_value().
-type openapi_spec() :: #{openapi := binary(), info := #{title := binary(), version := binary(), summary => binary(), description => binary(), termsOfService => binary(), contact => openapi_contact(), license => openapi_license()}, paths := #{binary() => path_operations()}, webhooks => openapi_webhooks(), servers => [openapi_server()], security => [openapi_security_requirement()], components => #{schemas => #{binary() => openapi_schema()}, securitySchemes => #{binary() => openapi_security_scheme()}}}.
-type openapi_webhooks() :: #{binary() => path_operations()}.
-type parameter_input_spec() :: #{name := binary(), in := parameter_location(), required := boolean(), schema := spectra:sp_type_or_ref()}.
-type parameter_location() :: path | query | header | cookie.
-type parameter_spec() :: #{name := binary(), in := parameter_location(), required := boolean(), schema := spectra:sp_type_or_ref(), module := module()}.
-type path_operations() :: #{http_method() => openapi_operation()}.
-type request_body_spec() :: #{schema := spectra:sp_type_or_ref(), module := module(), content_type => binary()}.
-type response_header_input_spec() :: #{required => boolean(), schema := spectra:sp_type_or_ref()}.
-type response_header_spec() :: #{required => boolean(), schema := spectra:sp_type_or_ref(), module := module()}.
-type response_spec() :: #{description := binary(), schema => spectra:sp_type_or_ref(), module => module(), status_code => http_status_code(), content_type => binary(), headers => #{binary() => response_header_spec()}}.
-type webhook_spec() :: #{name := binary(), method := http_method(), responses := #{http_status_code() => response_spec()}, parameters := [parameter_spec()], request_body => request_body_spec(), nil_fields => null, doc => endpoint_doc()}.
Functions
-spec add_response(Endpoint :: endpoint_spec() | webhook_spec(), Response :: response_spec()) -> endpoint_spec() | webhook_spec().
Adds a complete response specification to an endpoint.
This function adds a response that was built using the response builder pattern: response/2, response_with_body/3-4, and response_with_header/4.
Example
Response = spectra_openapi:response(200, <<"Success">>),
Response2 = spectra_openapi:response_with_body(Response, Module, Schema),
Response3 = spectra_openapi:response_with_header(Response2, <<"X-Rate-Limit">>, Module, HeaderSpec),
Endpoint = spectra_openapi:add_response(Endpoint1, Response3).Returns
Updated endpoint map with the response added
-spec endpoint(Method :: http_method(), Path :: binary()) -> endpoint_spec().
Creates a basic endpoint specification.
Equivalent to calling endpoint/3 with an empty documentation map.
Returns
Endpoint map with method and path set
-spec endpoint(Method :: http_method(), Path :: binary(), Doc :: endpoint_doc()) -> endpoint_spec().
Creates an endpoint specification with documentation.
This function creates the foundation for an endpoint with the specified HTTP method, path, and documentation. Additional details like responses, request body, and parameters can be added using the with_* functions.
Documentation Fields
The Doc map can contain:
- summary: Short summary of the endpoint (binary)
- description: Detailed description (binary)
- operationId: Unique identifier for the operation (binary)
- tags: List of tags for grouping (list of binaries)
- deprecated: Whether the endpoint is deprecated (boolean)
- externalDocs: External documentation link (map with url and optional description)
- security: Security requirements for this operation, overriding the global default ([] opts out)
Returns
Endpoint map with method, path, and documentation set
-spec endpoints_to_openapi(MetaData :: openapi_metadata(), Endpoints :: [endpoint_spec()]) -> {ok, json:encode_value() | iodata()} | {error, [spectra:error()]}.
Generates a complete OpenAPI 3.1 specification from a list of endpoints.
This function takes a list of endpoint specifications and generates a complete OpenAPI document with paths, operations, and component schemas.
Returns
{ok, OpenAPISpec} containing the complete OpenAPI 3.1 document, or {error, Errors} if generation fails
-spec endpoints_to_openapi(MetaData :: openapi_metadata(), Endpoints :: [endpoint_spec()], Options :: [spectra:schema_option()]) -> {ok, json:encode_value() | iodata()} | {error, [spectra:error()]}.
-spec format_error(Reason :: term(), StackTrace :: erlang:stacktrace()) -> #{pos_integer() | general => unicode:chardata()}.
Formats the badarg errors raised by with_nil_fields/2 and to_openapi/4.
Called by erl_error and by Elixir to build the error message.
-spec response(StatusCode :: http_status_code(), Description :: binary()) -> response_spec().
Creates a response builder for constructing response specifications.
This function creates a response builder that can be incrementally configured with body and headers before being added to an endpoint using add_response/2.
Example
Response = spectra_openapi:response(200, <<"Success">>),
Response2 = spectra_openapi:response_with_body(Response, Module, Schema),
Response3 = spectra_openapi:response_with_header(Response2, <<"X-Rate-Limit">>, Module, HeaderSpec),
Endpoint = spectra_openapi:add_response(Endpoint1, Response3).Returns
Response builder map with status code and description
-spec response_with_body(Response :: response_spec(), Module :: module(), Schema :: spectra:sp_type_or_ref()) -> response_spec().
Adds a response body to a response builder.
This function sets the schema and module for the response body. Use this with response/2 to build up a complete response specification.
Returns
Updated response builder with body schema added
-spec response_with_body(Response :: response_spec(), Module :: module(), Schema :: spectra:sp_type_or_ref(), ContentType :: binary()) -> response_spec().
Adds a response body with custom content type to a response builder.
This function sets the schema, module, and content type for the response body. Use this with response/2 to build up a complete response specification.
Returns
Updated response builder with body schema and content type added
-spec response_with_header(Response :: response_spec(), HeaderName :: binary(), Module :: module(), HeaderSpec :: response_header_input_spec()) -> response_spec().
Adds a header to a response builder.
This function adds a header specification to the response being built. Multiple headers can be added by calling this function multiple times.
description and deprecated for the header are sourced automatically from the
-spectra() annotation on the schema type.
Returns
Updated response builder with header added
-spec to_openapi(MetaData :: openapi_metadata(), Endpoints :: [endpoint_spec()], Webhooks :: [webhook_spec()], Options :: [spectra:schema_option()]) -> {ok, json:encode_value() | iodata()} | {error, [spectra:error()]}.
Generates a complete OpenAPI 3.1 specification from endpoints and webhooks.
Webhooks are emitted under the top-level webhooks key, keyed by the event name
given to webhook/2-3. Their schemas share components/schemas with the
endpoints, so a type used by both is emitted once.
A global security requirement in the metadata is emitted at the top level and
therefore applies to webhook operations too, per OpenAPI - even though its
meaning is inverted there, since it would describe this API authenticating to
the consumer. Give a webhook its own security in its Doc map to override that,
or security => [] to opt it out entirely.
Returns
{ok, OpenAPISpec} containing the complete OpenAPI 3.1 document, or {error, Errors} if generation fails
-spec webhook(Name :: binary(), Method :: http_method()) -> webhook_spec().
Creates a webhook specification.
Equivalent to calling webhook/3 with an empty documentation map.
Returns
Webhook map with name and method set
-spec webhook(Name :: binary(), Method :: http_method(), Doc :: endpoint_doc()) -> webhook_spec().
Creates a webhook specification with documentation.
Webhooks are keyed by event name and emitted under the OpenAPI 3.1 top-level
webhooks key. The request body is the payload this API sends, and the
responses describe what the consumer returns. Build them with the same
with_* functions as endpoints; path and query parameters are rejected.
Documentation Fields
The Doc map takes the same fields as endpoint/3.
Example
Webhook = spectra_openapi:webhook(<<"userCreated">>, post, #{summary => <<"User created">>}),
Webhook1 = spectra_openapi:with_request_body(Webhook, Module, {type, user, 0}),
Webhook2 = spectra_openapi:add_response(
Webhook1, spectra_openapi:response(200, <<"Acknowledged">>)
).Returns
Webhook map with name, method, and documentation set
-spec with_nil_fields(Webhook :: webhook_spec(), NilFields :: null) -> webhook_spec().
Makes the webhook payload write every missing value as null.
Use it when the code that sends the webhook encodes the payload with the
{nil_fields, null} option of spectra:encode/5. The payload schema then lists
every field whose type can be missing in required and allows null for it,
nested types included. Headers and response schemas do not change.
The payload type keeps its normal schema name. If the same type is also used
without this option, this webhook gets a second schema with Nullable added to
the name. Under the nil_fields setting null the option changes nothing, and
under omit to_openapi/4 raises badarg, because that setting does not
allow the per-call {nil_fields, null} option.
Returns
Webhook map with nil_fields set
-spec with_parameter(Endpoint :: endpoint_spec() | webhook_spec(), Module :: module(), ParameterSpec :: parameter_input_spec()) -> endpoint_spec() | webhook_spec().
Adds a parameter specification to an endpoint.
This function adds a parameter (path, query, header, or cookie) to the endpoint. Multiple parameters can be added by calling this function multiple times.
Parameter Specification
The parameter spec should be a map with these keys:
- name: Parameter name (binary, required)
in: Parameter location (path | query | header | cookie, required)
- required: Whether the parameter is required (boolean, required)
- schema: Schema reference or direct type (spectra:sp_type_or_ref(), required)
description and deprecated are sourced automatically from the -spectra() annotation
on the schema type and should not be included in the parameter spec.
Returns
Updated endpoint map with the new parameter added
-spec with_request_body(Endpoint :: endpoint_spec() | webhook_spec(), Module :: module(), Schema :: spectra:sp_type_or_ref()) -> endpoint_spec() | webhook_spec().
Adds a request body to an endpoint.
This function sets the request body schema for the endpoint.
Typically used with POST, PUT, and PATCH endpoints. The content type defaults
to application/json. Use with_request_body/4 to override it.
The description and deprecated fields in the generated OpenAPI
requestBody object are sourced automatically from the -spectra()
attribute on the schema type — there is no parameter for overriding them
on this call.
Example
-spectra(#{description => <<"User to create">>}).
-type create_user_request() :: #create_user_request{}.
Endpoint = spectra_openapi:with_request_body(
spectra_openapi:endpoint(post, <<"/users">>),
my_module,
create_user_request
).Returns
Updated endpoint map with request body set
-spec with_request_body(Endpoint :: endpoint_spec() | webhook_spec(), Module :: module(), Schema :: spectra:sp_type_or_ref(), ContentType :: binary()) -> endpoint_spec() | webhook_spec().
Adds a request body to an endpoint with a custom content type.
Like with_request_body/3 but overrides the default content type
(application/json). ContentType must be a binary such as
<<"application/xml">>.
The description and deprecated fields in the generated OpenAPI
requestBody object are sourced automatically from the -spectra()
attribute on the schema type.
Example
Endpoint = spectra_openapi:with_request_body(
spectra_openapi:endpoint(post, <<"/upload">>),
my_module,
upload_request,
<<"application/octet-stream">>
).Returns
Updated endpoint map with request body set