open-api-spex / open_api_spex

Open API Specifications for Elixir Plug applications
Mozilla Public License 2.0
701 stars 183 forks source link

Recursive schema not handled correctly? #627

Open jarmo opened 1 month ago

jarmo commented 1 month ago

Hi! Thank you for this library.

I have a problem with describing a recursive schema, which looks something like this in the response JSON:

[
  {
    "name": "foo",
    "children": [
      {
        "name": "bar",
        "children": [
          {
            "name": "baz",
            "children": []
          }
        ]
      }
    ]
  }
]

Basically it represents a tree of nodes of nodes of nodes...

I tried something like this (already figured it out that there's a need to use Reference instead of module itself to avoid compilation errors):

defmodule MyAppWeb.Schemas do
  alias OpenApiSpex.Schema
  alias OpenApiSpex.Reference

  defmodule Node do
    require OpenApiSpex

    OpenApiSpex.schema(%{
      type: :object,
      properties: %{
        name: %Schema{type: :string, description: "Node name"},
        children: %Reference{"$ref": "#/components/schemas/Nodes"}
      },
      required: [:name, :children]
    })
  end

  defmodule Nodes do
    require OpenApiSpex

    OpenApiSpex.schema(%{
      type: :array,
      items: Node,
      minLength: 0
    })
  end
end

This produces an output in the Swagger UI where everything seems to be correct except Node.children is shown as an array of anonymous objects, but nothing about it being array of Node.

How should a relation like this be described so that Swagger UI would at least show the type of array elements for children property?

zorbash commented 4 weeks ago

Hi @jarmo,

I created this notebook to reproduce the issue, I'm using Reference in both schemas.

The version of swagger UI used by https://editor.swagger.io/ does not show Node.children as an array of anonymous objects.

Screenshot 2024-08-16 at 16 00 44

jarmo commented 4 weeks ago

@zorbash thank you for your input!

I tried my schema at https://editor.swagger.io/ too and it worked as expected - recursiveness was shown correctly! I suspect this means that the problem is not in open_api_spex per se, but the problem is that it does not include up-to-date version of Swagger UI. Currently I'm serving it via Phoenix app as described in the README at https://github.com/open-api-spex/open_api_spex?tab=readme-ov-file#serve-swagger-ui

What would be the best possible way to serve a different version of Swagger UI by Phoenix when it comes to open_api_spex? I can imagine that I could download all the assets (or use CDN) and serve it as a static asset instead of relying on open_api_spex somehow, but is that the recommended way?

zorbash commented 4 weeks ago

There's doesn't seem to be a way to configure the swagger ui version in OpenApiSpex.Plug.SwaggerUI. My suggestion would be to always to point to latest (ie https://cdn.jsdelivr.net/npm/swagger-ui-dist/swagger-ui.min.css) but allow setting to a specific version using a compile_env config.

jarmo commented 4 weeks ago

I would suggest using unpkg.com instead since it seems to be the "official" recommendation by SwaggerUI (https://github.com/swagger-api/swagger-ui/blob/HEAD/docs/usage/installation.md) so in this case https://unpkg.com/swagger-ui-dist/swagger-ui.css

jarmo commented 4 weeks ago

Consider it done via PR #628