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

Schema oneOf among integer and string doesn't work with integer in a string ("1234") #578

Open
davidjulien opened this issue Dec 5, 2023 · 1 comment

Comments

@davidjulien
Copy link

davidjulien commented Dec 5, 2023

Hi!

I would like to define a field id as an integer or a string. Thus I write this schema:

  OpenApiSpex.schema(%{
    oneOf: [
      %Schema{type: :integer},
      %Schema{type: :string}
    ]
  })

It works when my data is an integer 1234 or a string "my_id". But it doesn't work when it is an integer inside a string "1234". It triggers this error:

Value does not conform to schema:
Failed to cast value to one of: more than one schemas validate at .../id

I think that the reason is here. In the module Cast.Integer, we convert the value to integer when it is a binary containing an integer. Consequently, the two clauses of my oneOf are valid.

def cast(%{value: value} = ctx) when is_binary(value) do
case Integer.parse(value) do
{value, ""} -> cast(%{ctx | value: value})
_ -> Cast.error(ctx, {:invalid_type, :integer})
end
end

Is there a workaround or can we remove this function clause?

I tried with anyOf instead of oneOf but in that case I have this error:

 ** (Protocol.UndefinedError) protocol Enumerable not implemented for 1234 of type Integer. This protocol is implemented for the following type(s): ...

Thank you

@davidjulien
Copy link
Author

Here is a possible workaround:

  defmodule StrictIntegerValidation do
    @moduledoc """
    Ensure that we have really an integer, and not an integer inside a string
    """
    def cast(ctx) do
      if is_integer(ctx.value) do
        {:ok, ctx.value}
      else
        {:error, "Not strictly integer"}
      end
    end
  end

  OpenApiSpex.schema(%{
    oneOf: [
      %Schema{type: :string},
      %Schema{type: :integer, "x-validate": StrictIntegerValidation}
    ]
  })

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

No branches or pull requests

1 participant