web-dev-qa-db-fra.com

Schéma JSON concernant l'utilisation de $ ref

Je comprends que $ ref prend un URI vers un schéma json à utiliser, mais où pointe $ ref: "#"? Cela signifie-t-il simplement utiliser le schéma actuel pour ce niveau de bloc? Ou cela signifie-t-il d'utiliser le schéma de niveau racine défini dans l'ID de niveau racine? Merci

EDIT: Donc, si j'ai:

"items": {
        "anyOf": [
            { "$ref": "#" },
            { "$ref": "#/definitions/schemaArray" }
        ],
        "default": {}
    }

Comme il manque un champ id, il tentera de valider les éléments d'instance avec le schéma racine en premier, puis si cela échoue, essayez de le valider avec le schéma schemaArray défini dans le schéma de définitions, non?

Donc, si je le change:

 "items": {
            "id" : "#/items",
            "anyOf": [
                { "$ref": "#" },
                { "$ref": "#/definitions/schemaArray" }
            ],
            "default": {}
        }

Ensuite, le premier sous-schéma dans le tableau anyOf pointera vers le schéma des éléments lui-même?

EDIT # 2: Bon alors si j'avais:

 "items": {
        "id" : "itemSchema",
        "anyOf": [
            { "$ref": "#" },
            { "$ref": "#/definitions/schemaArray" }
        ],
        "default": {}
    }

et

"stringArray": {
        "type": "array",
        "items": { "$ref" : "itemSchema" },
        "minItems": 1,
        "uniqueItems": true
    }

Le champ "items" de "stringArray" serait-il validé par rapport au "itemsSchema" ci-dessus?

Est-ce que le deuxième $ ref dans 'anyOf' fonctionne en allant à la racine puis en parcourant le chemin jusqu'à ce qu'il atteigne ce schéma? Merci!

30
hunterc

OK: chaque $ref est résolu en un URI complet. Une fois cela fait, toutes vos questions sont répondues en posant la question: Avec quel schéma devrais-je me retrouver, si je récupérais simplement cet URI? Où le $ref est, comment il a été chargé, tout cela n'est pas pertinent - il est entièrement dépendant de l'URI résolu.

La bibliothèque peut prendre certains raccourcis (comme la mise en cache des documents afin qu'ils ne soient récupérés qu'une seule fois, ou faire confiance à un schéma pour "parler pour" un autre), mais ceux-ci sont tous les détails de mise en œuvre.

Réponse à la question d'origine:

# n'est pas spécial: toutes les valeurs de $ref sont résolus en URI par rapport au document actuel (ou à la valeur la plus proche de "id", Si il y en a un).

Par conséquent, si vous n'avez pas utilisé "id", puis # pointera vers la racine du document de schéma. Si vous avez récupéré votre schéma à partir de http://example.com/schema, puis un {"$ref": "#"} n'importe où à l'intérieur qui résoudra en http://example.com/schema#, qui est le document lui-même.

C'est différent lorsque vous utilisez "id", car il modifie le schéma "de base" par rapport auquel $ref est résolu:

{
    "type": "array",
    "items": {
        "id": "http://example.com/item-schema",
        "type": "object",
        "additionalProperties": {"$ref": "#"}
    }
}

Dans cet exemple, le $ref se résout en http://example.com/item-schema#. Maintenant, si votre configuration de schéma JSON approuve le schéma qu'il possède déjà, il peut réutiliser la valeur de "items".

Cependant, le fait est qu'il n'y a rien de spécial à propos de # - il se résout simplement en un URI comme les autres.

Réponse à EDIT 1:

Votre premier exemple est correct.

Cependant, votre deuxième n'est malheureusement pas. Cela est dû à la façon dont fonctionne la résolution des fragments pour les URI: un fragment remplace complètement un autre. Lorsque vous résolvez le # contre la "id" valeur de #/items, vous ne vous retrouvez pas avec #/items encore - vous vous retrouvez avec #. Ainsi, dans votre deuxième exemple, la première entrée dans "anyOf" sera toujours résolu à la racine du document, comme dans le premier exemple.

Réponse à EDIT 2:

En supposant que le document est chargé à partir de http://example.com/my-schema, les URI complets de vos deux $refs sont:

  • http://example.com/itemSchema#
  • http://example.com/itemSchema#/definitions/schemaArray

Pour la première, la bibliothèque peut utilise le schéma qu'elle a déjà, mais il se peut que ce ne soit pas - après tout, en regardant les URI, http://example.com/my-schema pourrait ne pas être fiable pour représenter avec précision http://example.com/itemSchema.

Pour le second - cela ne fonctionnera pas, car le "itemSchema" n'a pas de "definitions" section, de sorte que $ref ne se résoudra pas du tout correctement.

35
cloudfeet