View Source Open API
Use with Phoenix
To set up the Open API endpoints for your application, first include the :open_api_spex
dependency:
{:open_api_spex, "~> 3.16"},
Then in the module where you call use AshJsonApi.Router
add the following option:
use AshJsonApi.Router, domains: [...], open_api: "/open_api"
Finally, you can use utilities provided by open_api_spex
to show UIs for your API. Be sure to put your forward
call last, if you are putting your API at a sub-path.
forward "/api/swaggerui",
OpenApiSpex.Plug.SwaggerUI,
path: "/api/open_api",
default_model_expand_depth: 4
forward "/api/redoc",
Redoc.Plug.RedocUI,
spec_url: "/api/open_api"
forward "/api", YourApp.YourApiRouter
Now you can go to /api/swaggerui
and /api/redoc
!
Use with Plug
To set up the open API endpoints for your application, first include the :open_api_spex
and :redoc_ui_plug
dependency:
{:open_api_spex, "~> 3.16"},
{:redoc_ui_plug, "~> 0.2.1"},
Then in the module where you call use AshJsonApi.Router
add the following option:
use AshJsonApi.Router, domains: [...], open_api: "/open_api"
Finally, you can use utilities provided by open_api_spex
to show UIs for your API. Be sure to put your forward
call last, if you are putting your API at a sub-path.
forward "/api/swaggerui",
to: OpenApiSpex.Plug.SwaggerUI,
init_opts: [
path: "/api/open_api",
default_model_expand_depth: 4
]
forward "/api/redoc",
to: Redoc.Plug.RedocUI,
init_opts: [
spec_url: "/api/open_api"
]
forward "/api", YourApp.YourApiRouter
Now you can go to /api/swaggerui
and /api/redoc
!
Customize values in the OpenAPI documentation
To customize the main values of the OpenAPI spec, a few options are available:
use AshJsonApi.Router,
domains: [...],
open_api: "/open_api",
open_api_title: "Title",
open_api_version: "1.0.0",
open_api_servers: ["http://domain.com/api/v1"]
If :open_api_servers
is not specified, a default server is automatically derived from your app's Phoenix endpoint, as retrieved from inbound connections on the open_api
HTTP route.
In case an active connection is not available, for example when generating the OpenAPI spec via CLI, you can explicitely specify a reference to the Phoenix endpoint:
use AshJsonApi.Router,
domains: [...],
open_api: "/open_api",
phoenix_endpoint: MyAppWeb.Endpoint
To override any value in the OpenApi documentation you can use the :modify_open_api
options key:
use AshJsonApi.Router,
domains: [...],
open_api: "/open_api",
modify_open_api: {__MODULE__, :modify_open_api, []}
def modify_open_api(spec, _, _) do
%{
spec
| info: %{spec.info | title: "MyApp Title JSON API", version: Application.spec(:my_app, :vsn) |> to_string()}
}
end
Generate spec files via CLI
You can write the OpenAPI spec file to disk using the Mix tasks provided by OpenApiSpex.
Supposing you have setup AshJsonApi as:
defmodule MyAppWeb.AshJsonApi
use AshJsonApi.Router, domains: [...], open_api: "/open_api"
end
you can generate the files with:
mix openapi.spec.json --spec MyAppWeb.AshJsonApi
mix openapi.spec.yaml --spec MyAppWeb.AshJsonApi
Setting a route prefix for generated files
The route prefix in normal usage is automatically inferred, but when generating files we will use the
prefix
option set in thejson_api
section of the relevantAsh.Domain
module.
To generate the YAML file you need to add the ymlr dependency.
def deps do
[
{:ymlr, "~> 2.0"}
]
end
You can also use the --check
option to confirm that your checked in spec file(s) match.
mix openapi.spec.json --spec MyAppWeb.AshJsonApiRouter --check
mix openapi.spec.yaml --spec MyAppWeb.AshJsonApiRouter --check
Using this file in production
To avoid generating the spec every time your open_api endpoint is hit, you can use
the open_api_file
option. Ensure that it points to an existing .json
file.
You will almost certainly want to do this only for production so that the schema
is generated dynamically in dev, but served statically in production.
open_api_file =
if Mix.env() == :prod do
"priv/static/open_api.json"
else
nil
end
use AshJsonApi.Router,
domains: [...],
open_api: "/open_api",
modify_open_api: {__MODULE__, :modify_open_api, []},
open_api_file: open_api_file
Known issues/limitations
Swagger UI
SwaggerUI does not properly render recursive types. This affects the examples and type documentation for the filter
parameter especially.
Redoc
Redoc does not show all available schemas in the sidebar. This means that some schemas that are referenced only but have no endpoints that refer to them are effectively un-discoverable without downloading the spec and hunting them down yourself.