Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

$ref and other properties in JSON Reference #136

Open
massadm opened this issue Oct 29, 2021 · 3 comments
Open

$ref and other properties in JSON Reference #136

massadm opened this issue Oct 29, 2021 · 3 comments

Comments

@massadm
Copy link

massadm commented Oct 29, 2021

namespace Swaggest\JsonSchema;
interface RemoteRefProvider
{
    public function getSchemaData($url);
}

Is it possible in getSchemaData to get an JSON object, which contains a member named $ref?

[...]
{
"title": "my_value",
"description": "my_value",
"$ref": "..."
}
[...]

I am aware of the limitations of a JSON Reference, but I need to do it in such a way that the properties with the value "my_value" from the example override the own properties of the schema referenced by $ref. To do this, in getSchemaData I need access to the object containing the $ref, the rest is trivial.

Any solution that works will do!

vearutop added a commit that referenced this issue Nov 14, 2021
@vearutop
Copy link
Member

@massadm, sorry for late response.

Please check example implementation in 22eadfe. I hope I understood your task correctly.

@massadm
Copy link
Author

massadm commented Nov 16, 2021

Thanks for the suggested solution. This solution is simple and effective, but not applicable in my case.

If I modify your example like this:

...
    public function testPatchSchema()
    {
        $refProvider = new Preloaded();
        $refProvider->setSchemaData(
            'https://example.com/unixtimestamp-type.json',
            json_decode(<<<'JSON'
{
	"title": "UNIX Timestamp",
	"description": "Number of seconds that have elapsed since the Unix epoch",
	"type": "integer"
}
JSON
            )
        );

        $schemaData = json_decode(<<<'JSON'
{
    "properties": {
        "atime": {
        	"title": "Access timestamp",
        	"description": "May not update if has been accessed recently",
        	"$ref":"https://example.com/unixtimestamp-type.json"
        },
        "mtime": {
        	"title": "Modification timestamp",
        	"$ref":"https://example.com/unixtimestamp-type.json"
        },
        "ctime": {
        	"title": "Change timestamp",
        	"$ref":"https://example.com/unixtimestamp-type.json"
        }
    }
}
JSON
        );
...

After:

...
$schema = Schema::import(...);
echo json_encode($schema, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);

I would like the result to be:

{
...
    "properties": {
        "atime": {
        	"title": "Access timestamp",
        	"description": "May not update if has been accessed recently",
        	"type": "integer"
        },
        "mtime": {
        	"title": "Modification timestamp",
        	"description": "Number of seconds that have elapsed since the Unix epoch",
        	"type": "integer"
        },
        "ctime": {
        	"title": "Change timestamp",
        	"description": "Number of seconds that have elapsed since the Unix epoch",
        	"type": "integer"
        }
    }
}

(titles and descriptions have merged)

So in getSchemaData() I need not only resource content but also entire object containing the $ref:

{
   "title": "Access timestamp",
   "description": "May not update if has been accessed recently",
   "$ref":"https://example.com/unixtimestamp-type.json"
}

That way I can get the fields to be merged.

I am aware of the limitations of a JSON Reference: when an object contains a $ref property, the object is considered a reference, not a schema. For me additional properties to the $ref is something like context for JSON-Pointer.

My case is specific of course. Now I use such constructions, but they are very cumbersome:

...
    "properties": {
        "atime": {
        	"title": "Access timestamp",
        	"description": "May not update if has been accessed recently",
        	"allOf": [{ "$ref": "https://example.com/unixtimestamp-type.json" }]
        },
...

@vearutop
Copy link
Member

Latest version of JSON schema spec allows keywords adjacent to $ref (originally defined in json-schema-org/json-schema-spec#628), unfortunately this library is stuck at draft-07 because I haven't had practical need for newer spec versions. I was planning to implement support for newer drafts, hopefully I will find time for that.

Using allOf to nest reference(s) was an idiomatic approach in draft-07.

Could you tell a bit more about your use case? What would you do with an instance of schema that has referenced value and titles/descriptions merged at top level?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants