jonasschmidt / ex_json_schema

An Elixir JSON Schema validator
MIT License
366 stars 98 forks source link

Validating Structs #10

Closed h4cc closed 8 years ago

h4cc commented 8 years ago

I tried to use this library but ran into a little bummer:

Using Poison to decode json directly into the structs i need, like this:

data = Poison.decode!("{foo: {bar: 42}}", as: %{
  "foo" => %Foo{},
})

When trying to validate the following schema on that Foo struct does not fail, but will return truewithout checking anything:

schema = ExJsonSchema.Schema.resolve(%{
    "type" => "object",
    "properties" => %{
      "bar" => %{
        "type" => "string",
      },
    },
  })
true = ExJsonSchema.Validator.validate(schema, data["foo"])

Is it possible to integrate checking Structs directly? At least letting the validate() fail for Structs that should be validated?

My workaround is this line to convert my Struct back to a stringed map:

map = for {k, v} <- Map.from_struct(data), into: %{}, do: {Atom.to_string(k), v}
jonasschmidt commented 8 years ago

I suspect the reason this does not work is because structs have symbol keys. I will look into it and see if there's an easy way to fix it.

jonasschmidt commented 8 years ago

Ok, so the more I think about it, the less it seems like this conversion should be handled by the validator. I think a JSON object should be represented as a Map with string keys in Elixir. JSON does not have the concept of a Symbol/Atom, so I think the (JSON) validator should not have to handle that either. So it seems more fitting to me to do the stringification before passing the data object to the validator.

So I'm leaning towards leaving things as they are. The fact that sometimes you will have Strings and sometimes Atoms as Map keys is an possible pitfall in all languages that make that kind of distinction. So users are bound to frequently have that annoying experience anyway ;)

jonasschmidt commented 8 years ago

It might also be a better pattern to first validate the JSON you get as input and then turn it into a Struct. At that point you can be certain that it has all the right properties with the correct types, and you don't have to use Poison to do a part of that validation for you anymore.

h4cc commented 8 years ago

Thanks for the explanation. :+1: