Skip to content

Cannot use local JSON file #46

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

Closed
iursevla opened this issue Jul 6, 2018 · 8 comments · Fixed by #47
Closed

Cannot use local JSON file #46

iursevla opened this issue Jul 6, 2018 · 8 comments · Fixed by #47

Comments

@iursevla
Copy link
Contributor

iursevla commented Jul 6, 2018

I'm using php-json-schema to validate the responses of my server endpoints.

I'm testing it locally and i can't seem to find a way to reference another schma with definitions.

My endpoint schema validator has the following:
"tasks": { "$ref": "definitions.json#/taskDefinition"},

The other file called definitions.json has the following:

{
  "taskDefinition": {
    "type": "array"
  }
}

It always returns an error:

file_get_contents(definitions.json): failed to open stream: No such file or directory
 /home/ralves/projects/php-project/vendor/swaggest/json-schema/src/RemoteRef/BasicFetcher.php:14
 /home/ralves/projects/php-project/vendor/swaggest/json-schema/src/RefResolver.php:195
 /home/ralves/projects/php-project/vendor/swaggest/json-schema/src/Schema.php:698
 /home/ralves/projects/php-project/vendor/swaggest/json-schema/src/Schema.php:1139
 /home/ralves/projects/php-project/vendor/swaggest/json-schema/src/Wrapper.php:46
 /home/ralves/projects/php-project/vendor/swaggest/json-schema/src/Schema.php:863
 /home/ralves/projects/php-project/vendor/swaggest/json-schema/src/Schema.php:1139
 /home/ralves/projects/php-project/vendor/swaggest/json-schema/src/Schema.php:831
 /home/ralves/projects/php-project/vendor/swaggest/json-schema/src/Schema.php:1139
 /home/ralves/projects/php-project/vendor/swaggest/json-schema/src/Schema.php:176
 /home/ralves/projects/php-project/vendor/swaggest/json-schema/src/Wrapper.php:58
 /home/ralves/projects/php-project/vendor/swaggest/json-schema/src/Structure/ClassStructureTrait.php:60
 /home/ralves/projects/php-project/vendor/swaggest/json-schema/src/Schema.php:137
 /home/ralves/projects/php-project/tests/api/AuthenticatedCest.php:77
 /home/ralves/projects/php-project/tests/api/CoreCest.php:12
 /tmp/ide-codeception.php:494

I tried using id: "file://", and a bunch of other things but didn't found a way to make it work.

I changed the code of the BasicFetcher.php so that the $url is the absolute path of the definitions.json file and it worked, but clearly it's not a solution for this problem.

PS: Searching on google for similar problem got me on this issue of another project

@vearutop
Copy link
Member

vearutop commented Jul 6, 2018

In order to refer external schema you need to provide it to validator. It works automatically for HTTP-accessible resources, but for local files and any other identifiers it is manual.

Here is an example what you likely need to do:

// Create references provider
$refProvider = new Preloaded();
$refProvider->setSchemaData(
    'definitions.json',
    json_decode(file_get_contents('/path/to/definitions.json'))
);

// Create custom validation context
$options = new Context();
$options->remoteRefProvider = $refProvider;

$schemaData = json_decode(<<<'JSON'
{
    "properties": {
        "tasks": { "$ref": "definitions.json#/taskDefinition"}
    }
}
JSON
);

// Create validator instance with custom validation context
$schema = Schema::import($schemaData, $options);

Another example in test suite.


It is quite common to refer to local resources by file:// so I'll implement automatic support for that.

Just be aware that uri in schema is an identifier first of all, not necessarily accessible with conventional protocols.

@iursevla
Copy link
Contributor Author

iursevla commented Jul 6, 2018

@vearutop thanks for your reply.

The solution you presented works but if i want to have multiple defintions files for each part of my application it's easier to use my current workaround (i think).
For now, I added a placeholder in the id tag and then I replace said placeholder with the path to my schemas fiolder and doing so each developer can use it's local files.

"id": "{{SCHEMA_PATH}}/mainPage/",

and then in my code i do:

jsonSchema = json_decode(file_get_contents($absoluteSchemaPath));
str_replace('{{SCHEMA_PATH}}', self::SCHEMAS_PATH, $jsonSchema->id);
return Schema::import($jsonSchema);

For now this works and lets everyone use their definitions without the need for validators.

Your solution with file::// is the cleanest by far.

@massadm
Copy link

massadm commented Jul 6, 2018

Just be aware that uri in schema is an identifier first of all, not necessarily accessible with conventional protocols.

Hi! Absolutely. And give attention to "id" property which declares a base "URL" against which related $ref "URL"s are resolved.

You do not want file:// Schemas at all. All you want is some kind of mapping between schemas and files in storage so using Preloaded is the way.

BTW due to hi-load i use SchemaFactory and something like \unserialize(\gzinflate(\file_get_contents($cacheFile))) to almost instantly receive deployed Schema objects.

@vearutop
Copy link
Member

vearutop commented Jul 6, 2018

tagged 0.12.2

@massadm I agree that totally makes sense performance-wise.

@massadm
Copy link

massadm commented Jul 6, 2018

Please note that file://x refer to a non-local file. RFC8089

@vearutop
Copy link
Member

vearutop commented Jul 7, 2018

@massadm thanks, the main use-case is for absolute paths /somewhere/schema.json so it would be file:///somewhere/schema.json - a local file, but maybe it makes sense to ensure that file:/// is present in uri.

@massadm
Copy link

massadm commented Jul 7, 2018

@vearutop file_get_contents() fallback to file:// for any unrecognized protocol. So file:///... will be used in any case to accessing local filesystem.

@vearutop
Copy link
Member

vearutop commented Jul 9, 2018

@massadm oh, indeed, I didn't even think that file:// was already supported out of PHP box. :)

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

Successfully merging a pull request may close this issue.

3 participants