jonasschmidt / ex_json_schema

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

Expected field not given, but validation is ok #4

Closed the-guitarman closed 8 years ago

the-guitarman commented 8 years ago

My schema expects the team_name field to be a string field.

schema = %{
  "type" => "object",
  "properties" => %{
    "team_name" => %{"type" => "string"},
    "matches"   => %{
      "type"       => "array",
      "properties" => %{
        "start_at" => %{"type" => "string"},
        "home"     => %{"type" => "string"},
        "guest"    => %{"type" => "string"}
      }
    }
  }
}

But the given json string has no team_name field.

json_b = "{
  \"matches\": [
      {\"start_at\": \"Sonntag, 13.03.2016 - 12:00 Uhr\", 
      \"home\": \"Opponent Team 1\", 
      \"guest\": \"My Team\"
    }, {
      \"start_at\": \"Sonntag, 03.04.2016 - 14:00 Uhr\", 
      \"home\": \"My Team\", 
      \"guest\": \"Opponent Team 2\"
    }
  ]
}"

I decode the string and get a map.

{:ok, map_b} = JSON.decode(json_b)                                                                                                                     
# {:ok, %{
#   "matches" => [
#     %{
#       "guest" => "My Team", 
#       "home" => "Opponent Team 1",
#       "start_at" => "Sonntag, 13.03.2016 - 12:00 Uhr"
#     },
#     %{
#       "guest" => "Opponent Team 2",
#       "home" => "My Team",
#       "start_at" => "Sonntag, 03.04.2016 - 14:00 Uhr"
#     }
#   ]
# }

I validate the map and get :ok.

schema |> ExJsonSchema.Schema.resolve |> ExJsonSchema.Validator.validate(map_b)
# :ok

I expect to get an :error. There's something wrong.

Elixir 1.2.2 ex_json_schema 0.3.1

jonasschmidt commented 8 years ago

You have to mark mandatory properties as required, otherwise JSON Schema does not care whether they're there or not. So if you want team_name to be a required property, your schema should look like this:

%{
  "type" => "object",
  "properties" => %{
    "team_name" => %{"type" => "string"},
    "matches"   => %{
      "type"       => "array",
      "properties" => %{
        "start_at" => %{"type" => "string"},
        "home"     => %{"type" => "string"},
        "guest"    => %{"type" => "string"}
      }
    }
  },
  "required" => ["team_name"]
}

I would also recommend to have your dates in ISO 8601, then you can use "format": "date-time" for that property in your schema to have them properly validated.

the-guitarman commented 8 years ago

For all who are looking for more information. See: Validating Data in Elixir with ExJsonSchema

jonasschmidt commented 8 years ago

Yes, that's a good article. I'd also recommend checking out http://spacetelescope.github.io/understanding-json-schema/ for a more extensive JSON Schema tutorial.