Skip to content

Commit

Permalink
Document schema resolver duplicate titles behaviour
Browse files Browse the repository at this point in the history
  • Loading branch information
zorbash committed Mar 6, 2025
1 parent 620c57e commit 29b40e5
Show file tree
Hide file tree
Showing 3 changed files with 281 additions and 193 deletions.
12 changes: 11 additions & 1 deletion lib/open_api_spex.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,17 @@ defmodule OpenApiSpex do
Then the `UserResponse.schema()` function will be called to load the schema, and
a `Reference` to the loaded schema will be used in the operation response.
See `OpenApiSpex.schema` macro for a convenient syntax for defining schema modules.
See `OpenApiSpex.schema/2` macro for a convenient syntax for defining schema modules.
> #### Known Issues {: .info}
>
> Resolving schemas expects the schema title to be unique for the generated references to be unique.
>
> For schemas defined with the `OpenApiSpex.schema/2` macro, the title is automatically set
> to the last part of module name. For example `MyAppWeb.Schemas.User` will have the title `"User"`,
> and `MyAppWeb.OtherSchemas.User` **will also** have the title `"User"` which can lead to conflicts.
>
> The recommendation is to set the title explicitly in the schema definition.
"""
@spec resolve_schema_modules(OpenApi.t()) :: OpenApi.t()
def resolve_schema_modules(spec = %OpenApi{}) do
Expand Down
20 changes: 16 additions & 4 deletions lib/open_api_spex/schema_resolver.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ defmodule OpenApiSpex.SchemaResolver do
@moduledoc """
Internal module used to resolve `OpenApiSpex.Schema` structs from atoms.
"""

alias OpenApiSpex.Discriminator

alias OpenApiSpex.{
Expand Down Expand Up @@ -29,7 +30,17 @@ defmodule OpenApiSpex.SchemaResolver do
Then the `UserResponse.schema()` function will be called to load the schema, and
a `Reference` to the loaded schema will be used in the operation response.
See `OpenApiSpex.schema` macro for a convenient syntax for defining schema modules.
See `OpenApiSpex.schema/2` macro for a convenient syntax for defining schema modules.
> #### Known Issues {: .info}
>
> Resolving schemas expects the schema title to be unique for the generated references to be unique.
>
> For schemas defined with the `OpenApiSpex.schema/2` macro, the title is automatically set
> to the last part of module name. For example `MyAppWeb.Schemas.User` will have the title `"User"`,
> and `MyAppWeb.OtherSchemas.User` **will also** have the title `"User"` which can lead to conflicts.
>
> The recommendation is to set the title explicitly in the schema definition.
"""
@spec resolve_schema_modules(OpenApi.t()) :: OpenApi.t()
def resolve_schema_modules(spec = %OpenApi{}) do
Expand Down Expand Up @@ -197,14 +208,15 @@ defmodule OpenApiSpex.SchemaResolver do
Enum.map_reduce(schema_list, schemas, &resolve_schema_modules_from_schema/2)
end

defp resolve_schema_modules_from_schema(schema, schemas) when is_atom(schema) do
title = schema.schema().title
defp resolve_schema_modules_from_schema(schema_module, schemas) when is_atom(schema_module) do
schema = schema_module.schema()
title = schema.title

new_schemas =
if Map.has_key?(schemas, title) do
schemas
else
{new_schema, schemas} = resolve_schema_modules_from_schema(schema.schema(), schemas)
{new_schema, schemas} = resolve_schema_modules_from_schema(schema, schemas)
Map.put(schemas, title, new_schema)
end

Expand Down
Loading

0 comments on commit 29b40e5

Please sign in to comment.