Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support generating OpenAPI spec files with Mix tasks #200

Merged
merged 4 commits into from
Jul 5, 2024

Conversation

davidebriani
Copy link
Contributor

@davidebriani davidebriani commented Jul 5, 2024

The PR adds support for generating OpenAPI spec files with Mix tasks, instead of just in response to HTTP requests to the OpenAPI route.

Some new options are introduced that helps customizing the resulting spec:

  • The OpenAPI title is now configurable with the :open_api_title opt.
  • The OpenAPI version is now configurable with the :open_api_version opt.
  • The OpenAPI server list was previously populated by getting the endpoint from a live conn. Since we want to support spec generation from the CLI and without access to an active connection, a new option :phoenix_endpoint is supported to statically provide a reference to the endpoint. Another option :open_api_servers is added if the user instead wants to specify a custom list of URLs.
defmodule MyAppWeb.AshJsonApi do
  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"],
    phoenix_endpoint: MyAppWeb.Endpoint
end

The OpenAPI spec can be written to file using the Mix tasks provided by OpenApiSpex.

mix openapi.spec.json --spec MyAppWeb.AshJsonApi
mix openapi.spec.yaml --spec MyAppWeb.AshJsonApi

A new section is added to the documentation to describe how to use the new options and how to generate the spec file via CLI.

Fixes #129

Contributor checklist

  • Bug fixes include regression tests
  • Features include unit/acceptance tests

We strive to be able to generate the OpenAPI spec with Mix commands, and
not only by querying an HTTP route.

As a preliminar step for further developments, move the spec generation
to the OpenAPI module in order to have a more reusable `spec` function
instead of having it tied to the controller.

Notes:
- Even though the OpenAPI module is not strictly related to HTTP
connections, the spec function accepts a `conn` argument since it was
already needed and provided to the `modify_open_api` function, if the
user specifies it in the opts. The `conn` argument is nil-able since we
want to support spec generation from the CLI.
- The OpenAPI title is now configurable with the `:open_api_title` opt.
- The OpenAPI version is now configurable with the `:open_api_version`
opt.
- The OpenAPI server list was previously populated by getting the
endpoint from a live `conn`. Since we want to support spec generation
from the CLI and without access to an active connection, a new option
`:phoenix_endpoint` is supported to statically provide a reference to
the endpoint. Another option `:open_api_servers` is added if the user
instead wants to specify a custom list of URLs.

Signed-off-by: Davide Briani <davide@briani.dev>
If OpenApiSpex is present, the `spec/0` function is exposed on the
Router.
This allows a user who has already configured AshJsonApi

```elixir
defmodule MyAppWeb.AshJsonApi
  use AshJsonApi.Router, domains: [...], open_api: "/open_api"
end
```

to directly generate the OpenAPI spec by running one the Mix tasks from
OpenApiSpex:

```sh
mix openapi.spec.json --spec MyAppWeb.AshJsonApi
mix openapi.spec.yaml --spec MyAppWeb.AshJsonApi
```

Signed-off-by: Davide Briani <davide@briani.dev>
Add some details about the available options to customize the values of
the OpenAPI spec.
Add a section to describe how the spec files can be generated with Mix
tasks.

Signed-off-by: Davide Briani <davide@briani.dev>
The option is not supported by OpenApiSpex.Plug.SwaggerUI and has no
effect.
To configure the title of the OpenAPI spec, a specific option has been
added on AshJsonApi.Router.

Signed-off-by: Davide Briani <davide@briani.dev>
@zachdaniel
Copy link
Contributor

YES 🙇

There is one major thing that I would like to see, but we will need to PR it to open_api_spex, which is a --check option, which fails with a message if the open api spec that is generated does not match the existing one. This allows people to put this mix task in their CI pipeline to ensure that the files don't get out of sync.

@zachdaniel
Copy link
Contributor

Actually, perhaps we should make our own wrapper tasks that support the --check option. This also gives us a chance to enrich those tasks further in the future if needed? i.e mix ash_json_api.spec.json and mix ash_json_api.spec.yaml?

@zachdaniel
Copy link
Contributor

For now, we can merge this as-is though, and consider that option as a follow up. Great work! 🥳

@zachdaniel
Copy link
Contributor

One other thing I'd like to follow up with is to support actually using the generated file, instead of regenerating it each time. This will make the schema faster to load as well.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Generate the OpenApi document of the project into a file
2 participants