On Thu, Nov 13, 2014 at 09:32:46PM +0200, Ron wrote:
> Yup, it's possible. The way to describe it would be:
>
> {
> "definitions": {
> "Request": {
> "properties": {
> "name": {
> "type": "string"
> }
> }
> },
> "Response": {
> "allOf": [
> {
> "$ref": "#/definitions/Request"
> },
> {
> "properties": {
> "id": {
> "type": "string"
> }
> }
> }
> ]
> }
> }
> }
I'm looking into this today, and I'm not sure how this scales with
required properties. The Swagger 2 examples have [1]:
…
"pet": {
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
},
"tag": {
"type": "string"
}
}
},
"newPet": {
"allOf": [
{
"$ref": "pet"
},
{
"required": [
"name"
],
"properties": {
"id": {
"type": "integer",
"format": "int64"
}
}
}
]
},
…
Is that even valid? The second schema in the allOf requires ‘name’
but only defines ‘id’? I suppose it doesn't set additionalProperties
to false, so it's saying, “you have to have a ‘name’ field which can
be whatever you want, and if you have an ‘id’ field it should be an
int64”. Why specify ‘id’ there at all?
In any case, since allOf validates each schema in isolation [2], the
initial ‘pet’ schema (the first entry in the allOf) is *still
requiring an ‘id’ parameter*. Isn't it? I think what we need is
something like this:
…
"identifiableObject": {
"properties": {
"id": {
"type": "integer",
"format": "int64"
}
},
"required": [
"id"
]
},
"newPet": {
"properties": {
"name": {
"type": "string"
},
"tag": {
"type": "string"
}
},
"required": [
"name"
]
},
"pet": {
"allOf": [
{
"$ref": "newPet"
},
{
"$ref": "identifiableObject"
}
]
},
…
That should (I think ;) add the required ‘id’ parameter to ‘pet’ that
doesn't apply to ‘newPet’. However, ‘id’ would still be a valid
parameter because we weren't disabling additionalProperties.
Unfortunately, disabling additionalProperties does not work well with
composable schemas [3,4]. You can get around that by making ‘_pet’
the base schema, with a ‘pet’ schema that also requires an ‘id’ and a
‘newPet’ schema that also limits additional properties (but doesn't
specify the property values):
…
"identifiableObject": {
"properties": {
"id": {
"type": "integer",
"format": "int64"
}
},
"required": [
"id"
]
},
"_pet": {
"properties": {
"name": {
"type": "string"
},
"tag": {
"type": "string"
}
},
"required": [
"name"
]
},
"pet": {
"allOf": [
{
"$ref": "_pet"
},
{
"$ref": "identifiableObject"
}
]
},
"newPet": {
"allOf": [
{
"$ref": "_pet"
},
{
"properties": {
"name": {},
"tag": {}
},
"additionalProperties": false
}
]
},
…
Where I've used the ‘{}’ free-form schema supported by blaze_compiler
(which also supports ‘{type: "any"}’ for free-form schemas [5] as does
Jsonary [6]). I couldn't find an explicit syntax for free-form
schemas in the JSON Schema spec [7,8]. The ‘any’ type is not
supported by the JSON Schema validation schema [9]. If the
empty-schema syntax isn't valid, you can create a free-form schema
locally with an ugly hack with ‘not’ [10]:
"unspecified": {
"anyOf": [
{
"type": null,
},
{
"not": {
"type": null,
}
}
]
}
to use in the ‘newPet’ definition. That's a lot of work to get a
‘pet’ type that explicitly requires an ‘id’ field and a ‘newPet’
version of that type that explicitly forbids an ‘id’ field. Am I
missing something obvious?
Thanks,
Trevor
[1]:
https://github.com/swagger-api/swagger-spec/blob/264e87e4666ee1cdb1441b17c2d1744c451dc8f7/examples/v2.0/json/petstore-expanded.json#L175
[2]:
http://spacetelescope.github.io/understanding-json-schema/reference/combining.html#allof
[3]:
https://github.com/json-schema/json-schema/issues/116
[4]:
https://groups.google.com/d/topic/json-schema/plynujOa75o/discussion
[5]:
https://www.npmjs.com/package/blaze_compiler
[6]:
http://jsonary.com/documentation/json-schema/?section=keywords/General%20keywords#keywords/General%20keywords/02%20-%20type
[7]:
http://json-schema.org/latest/json-schema-core.html#anchor8
[8]:
https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md#data-types
[9]:
http://json-schema.org/schema
[10]:
http://spacetelescope.github.io/understanding-json-schema/reference/combining.html#not
--
This email may be signed or encrypted with GnuPG (
http://www.gnupg.org).
For more information, see
http://en.wikipedia.org/wiki/Pretty_Good_Privacy