OpenApiSpex - OpenAPI / Swagger 3.0 for Plug APIs

@lessless can you elaborate on what you’re looking for?

OpenApiSpex doesn’t support reading external JSON/YAML files, but there is some flexibility in organizing the Elixir code.

Plug application example clarified it. I thought about extracting specs in separate .ex files and importing them later on, but having a module per http action is even better.

1 Like

Version 3.2.0 released.

Lots of internal improvements and some new features thanks to the wonderful contributors, particularly @moxley and the team at Ghost Group / Weedmaps. :heart:

Highlights:

  • Jason library support for JSON serialization
  • Improved memory usage
  • Improved error messages and validations
  • Integrate SwaggerUI with Plug.CSRFProtection

See the changelog for more details.

7 Likes

Version 3.4.0 released.

This version is required when using Phoenix 1.4.7+ and the OpenApiSpex.Paths.from_router/1 function.

Highlights:

  • Open API extensions can be added to the OpenApi document and the Info structs
  • Server.from_endpoint now uses the Phoenix API instead of the endpoint config to determine the URL
  • Compatibility with Phoenix 1.4.7 Router modules
4 Likes

amazing lib! thanks @mbuhot!
I loved the idea that the controller tests are guaranteeing the API protocol, so when our mobile/web devs (or us) access the swaggerui, they will see a guaranteed documentation

1 Like

In the example the api data is returned by show_operation which is just a function, so you can pull the %Operation{} data from anywhere.

1 Like

Version 3.5.0 is released!

This version has a lot of changes from the last several months. Highlights:

  • Ability to import Open API documents into OpenApiSpex, as an alternative to defining specs using using OpenApiSpex’ Elixir syntax.
  • Experimental support for ExDoc-based operation specs. Use doc tags in your controller to define operations instead of defining callback functions.
  • Improved Open API compliance and bug fixes for casting and validations
  • Deprecate the legacy cast & validate implementation for the newer Cast module.

Thank you to @mbuhot for letting me manage the release.

6 Likes

Version 3.6.0 is released!

This release include some enhancements and important bug fixes:

  • Feature: Improved inspect output of %Schema{} (#193)
  • Feature: Auto-populate schema title from module name (#192)
  • Feature: Derive Operation ID from meta in ExDoc specs (#195)
  • Fix: Validation of array minItems ignores empty array (#179)
  • Fix: Add minimum/maximum validation for number properties (#181)
  • Fix: Properly validate header params (#184)
  • Fix: Support free-form query parameters (#171)
  • Fix: Resolve schema modules from Response in Components (#186)
5 Likes

Is there an example for setting up authentication in the operations? I didn’t find in the example app. Thanks.

1 Like

Sorry no sample code for security yet, a PR to the example app would be most welcome!

It should be a matter of declaring the securitySchemes within the components section of your API spec, then referencing the schemes by name within each Operation.

https://swagger.io/docs/specification/authentication/

Are you using something simple like API keys or more complex like OpenIdConnect?

1 Like

Thanks for getting back. to me, I am using simple authorization with a bearer token, the same level of simplicity of API key. I got that working and I can open a PR with some documentation updates to guide other users as the example app does not require authorization.

PR with readme updates: https://github.com/open-api-spex/open_api_spex/pull/215

Version 3.7.0 is released!

This release include some enhancements and important bug fixes:

  • Enhancement: Multiple bug fixes and edge case handling of ExDoc based operation specs
  • Enhancement: Upgrade Swagger UI to 3.24.2 (#210)
  • Enhancement: Improve oneOf casting (#227)
  • Docs: Add SecurityScheme usage and examples in the readme (#215)
  • Fix: References for query params and discriminators with mappings not working (#200)
  • Fix: Errors in parameter pattern validation (#206)
  • Fix example (#212)
  • Fix: CastAndValidate: incorrect content-type handling (#218)
  • Fix: Can’t cast and validate a JSON array as request body (#229)
4 Likes

Hello,

I am wondering if it is possible to create a flag that uses the supportedSubmitMethods on the network configuration of SwaggerUI (https://github.com/swagger-api/swagger-ui/blob/master/docs/usage/configuration.md#user-content-supportedsubmitmethods) to disable the Try it Out feature for certain methods?

Great product btw!

I think we can add support for the configUrl option, allowing users to have a JSON file in priv/static that can be used to configure most of the swaggerUI options with needing to add flags in OpenApiSpex.

Interested in sending a PR? There’s a similar feature in the PhoenixSwagger SwaggerUI Plug that can be used for reference :slightly_smiling_face:

Thank you!

Version 3.8.0 is released!

This release comes with a couple of new features alongs with lots of enhancements and fixes:

  • Feature: Custom validators (#243)
  • Feature: Swagger json generation Mix Task (#249)
  • Feature: Customizable cache adapter (#262)
  • Enhancement: Allow passsing false to @doc annotation to skip the warning. (#236)
  • Enhancement: Make @doc parameters declaration consistent with open api (#237)
  • Enhancement: Support security @doc string attribute on operations (#251)
  • Enhancement: Allow a Reference to be used for directly in the parameters definition (#258)
  • Enhancement: Allow a Reference to be used for an Operation’s request body (#260)
  • Docs: Fixes README.md responses example typo “unprocessible” (#248)
  • Docs: Fix security example to use correct types for the keys (#239)
  • Fix: Remove default pop value for :type shortcut in @doc specs (#238)
  • Fix: Nested parameters when served from file based schema (#241)
  • Fix: Error handling for oneOf (#246)
  • Fix: json:api compatible data shape option for JsonRenderError (#245)
  • Fix: ReferenceError: components.parameter missing s in CastParamters (#257)
  • Fix: struct def for custom validators (#263)

As always, a huge thank you to all the contributors and maintainers for keeping the project going :heart:

4 Likes

Feel free to try out the swaggerui-config branch: https://github.com/open-api-spex/open_api_spex/pull/271

You can configure the supportedSubmitMethods (any many other options) like:

get "/swaggerui", OpenApiSpex.Plug.SwaggerUI,
      path: "/api/openapi",
      supported_submit_methods: [:get, :post],
      default_model_expand_depth: 3,
      display_operation_id: true

Thanks a lot for the latest release and also for the whole library. It’s really useful for me.

One thing I am not sure how to do is something like “polymorphic” schemas. This could be used for example with an endpoint returning 409 (conflict) with multiple meanings.
For example for one endpoint it means email is already registered or email is already invited. For some other endpoint 409 could mean some other options. I know I can create new Error.Conflict* schema for each endpoint and use the enum: [ ... ] atribute, but this could become quite non-DRY after a while.

I would really like something like

409 => {"Conflict", "application/json", Api.Schema.Conflict.new("email_already_registered", "email_already_used")

with the schema defined like this:

defmodule Api.Schema.Conflict do
  require OpenApiSpex
  alias OpenApiSpex.Schema

  def new(enum) do
    OpenApiSpex.schema(%{
      title: "Error.Conflict",
      type: :object,
      properties: %{
        error: %Schema{
          type: :object,
          properties: %{
            name: %Schema{
              type: :string,
              enum: enum,
              required: true
            },
            message: %Schema{type: :string}
          }
        }
      }
    })
  end
end

Is it possible or am trying to use a completely wrong approach? :slight_smile:

Interesting! How about if you construct the %Schema{} struct directly in new?

defmodule Api.Schema.Conflict do
  require OpenApiSpex
  alias OpenApiSpex.Schema

  def new(enum) do
    %Schema{
      title: "Error.Conflict",
      type: :object,
      properties: %{
        error: %Schema{
          type: :object,
          properties: %{
            name: %Schema{
              type: :string,
              enum: enum,
              required: true
            },
            message: %Schema{type: :string}
          }
        }
      }
    }
  end
end

It won’t define a struct for you, but it might be fine for a simple response schema?