Rhinosaurus
Rhinosaurus

Reputation: 1294

Is there a way to use JSON schemas to enforce values between fields?

I've recently started playing with JSON schemas to start enforcing API payloads. I'm hitting a bit of a roadblock with defining the schema for a legacy API that has some pretty kludgy design logic which has resulted (along with poor documentation) in clients misusing the endpoint.

Here's the schema so far:

{
    "type": "array",
    "items": {
        "type": "object",
        "properties": {
            "type": {
                "type": "string"
            },
            "object_id": {
                "type": "string"
            },
            "question_id": {
                "type": "string",
                "pattern": "^-1|\\d+$"
            },
            "question_set_id": {
                "type": "string",
                "pattern": "^-1|\\d+$"
            },
            "timestamp": {
                "type": "string",
                "format": "date-time"
            },
            "values": {
                "type": "array",
                "items": {
                    "type": "string"
                }
            }
        },
        "required": [
            "type",
            "object_id",
            "question_id",
            "question_set_id",
            "timestamp",
            "values"
        ],
        "additionalProperties": false
    }
}

Notice that for question_id and question_set_id, they both take a numeric string that can either be a -1 or some other non-negative integer.

My question: is there a way to enforce that if question_id is set to -1, that question_set_id is also set to -1 and vice-versa.

It would be awesome if I could have that be validated by the parser rather than having to do that check in application logic.


Just for additional context, I've been using python's jsl module to generate this schema.

Upvotes: 2

Views: 358

Answers (1)

Jason Desrosiers
Jason Desrosiers

Reputation: 24439

You can achieve the desired behavior by adding the following to your items schema. It asserts that the schema must conform to at least one of the schemas in the list. Either both are "-1" or both are positive integers. (I assume you have good reason for representing integers as strings.)

"anyOf": [
    {
        "properties": {
            "question_id": { "enum": ["-1"] },
            "question_set_id": { "enum": ["-1"] }
        }
    },
    {
        "properties": {
            "question_id": {
                "type": "string",
                "pattern": "^\\d+$"
            },
            "question_set_id": {
                "type": "string",
                "pattern": "^\\d+$"
            }
        }
    }

Upvotes: 1

Related Questions