Open xxmichas opened 1 month ago
Do you know what uniqueItems
work when the element type is object or another array?
Do you know what
uniqueItems
work when the element type is object or another array?
I did some research, and indeed it seems that uniqueItems
should validate the array items deeply (both nested objects and arrays).
Unfortunately spec is very minimalistic about uniqueItems
, but one of its authors (Henry Andrews) suggested using this tag here to validate an array of objects.
I tested the following schemas using Ajv and it did validate deeply for all of them. Ajv's docs.
You can use this online playground to quickly test them out.
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"users": {
"type": "array",
"items": {
"type": "object",
"properties": {
"userId": {
"type": "integer"
},
"username": {
"type": "string"
}
},
"required": ["userId", "username"],
"additionalProperties": false
},
"uniqueItems": true
}
},
"required": ["users"]
}
{
"users": [
{
"userId": 1,
"username": "user1"
},
{
"userId": 2,
"username": "user2"
}
]
}
{
"users": [
{
"userId": 1,
"username": "user1"
},
{
"userId": 1,
"username": "user1"
}
]
}
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"users": {
"type": "array",
"items": {
"type": "object",
"properties": {
"userId": {
"type": "integer"
},
"username": {
"type": "string"
},
"profile": {
"type": "object",
"properties": {
"email": {
"type": "string",
"format": "email"
},
"age": {
"type": "integer",
"minimum": 0
}
},
"required": ["email", "age"],
"additionalProperties": false
}
},
"required": ["userId", "username", "profile"],
"additionalProperties": false
},
"uniqueItems": true
}
},
"required": ["users"]
}
{
"users": [
{
"userId": 1,
"username": "user1",
"profile": {
"email": "user1@example.com",
"age": 25
}
},
{
"userId": 2,
"username": "user2",
"profile": {
"email": "user2@example.com",
"age": 30
}
}
]
}
{
"users": [
{
"userId": 1,
"username": "user1",
"profile": {
"email": "user1@example.com",
"age": 25
}
},
{
"userId": 1,
"username": "user1",
"profile": {
"email": "user1@example.com",
"age": 25
}
}
]
}
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"matrix": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "integer"
},
"uniqueItems": true
},
"uniqueItems": true
}
},
"required": ["matrix"]
}
{
"matrix": [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
}
{
"matrix": [
[1, 2, 3],
[1, 2, 3],
[4, 5, 6]
]
}
I also noticed a small issue with the current uniqueItems
implementation. When false is passed into tags.UniqueItems
, empty arrays and arrays with only one item are considered invalid, even though they should be valid.
Nested object and array case, I need to make special function for them.
By the way, using external function in the type tag is not possible now. It would be supported at v7 update, so that please wait for some months about that feature. Until that, just hope to satisfy only with atomic value unique checking like string[]
.
All good. Thank you for your amazing libraries.
A description of the problem you're trying to solve:
Currently, when defining arrays of primitive types, there is no built-in mechanism to enforce that array items are unique.
An overview of the suggested solution:
I propose adding a new tag for unique items in arrays, leveraging the
uniqueItems
property from the OpenAPI specification.OpenAPI documentation on uniqueItems: Swagger Data Types - uniqueItems
I'm unsure if
uniqueItems
should work on object-types (or if it's even possible to implement). Name could be adjusted to indicate that it only works on primitive types (if implementing it for object types is too hard).Code examples showing the expected behavior:
Examples of how the suggestion would work in various places: