Skip to content

$ref only supported at the root? #23

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
kevinsmith opened this issue Mar 6, 2019 · 8 comments
Closed

$ref only supported at the root? #23

kevinsmith opened this issue Mar 6, 2019 · 8 comments

Comments

@kevinsmith
Copy link

I may be missing something, but it appears that $ref is only recognized if it's at the root of the schema document. I tried following the example given in the documentation, but the $ref isn't even detected.

(When I move the $ref property to the root, it's detected, but it fails to load if ISchemaLoader isn't provided to Validator. Perhaps more an issue with documentation than the software itself.)

@sorinsarca
Copy link
Member

@kevinsmith can you provide a code snippet to reproduce this issue? I think it is a typo somewhere or maybe you forgot to register the schema.

@kevinsmith
Copy link
Author

kevinsmith commented Mar 6, 2019

It's the example from the documentation:

{
  "$id": "http://example.com/custom-email-validator.json#",
  
  "type": "string",
  "format": "email",
  "pattern": "@example\\.test$"
}

user-validator.json:

{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "minLength": 2
    },
    "email": {
      "$ref": "http://example.com/custom-email-validator.json#"
    }
  },
  "required": ["name", "email"],
  "additionalProperties": false
}

The validator is constructed like this:

$loader = new File('http://example.com/', ['path/to/schema/files/']);
$schema = $loader->loadSchema('http://example.com/user-validator.json');

$validator = new Validator(null, $loader);

$validator->schemaValidation(json_decode('{"sample":"request_body"}'), $schema);

I've placed a var_dump($ref); die; after this line

$ref = $schema->{'$ref'};

and it never gets called.

@sorinsarca
Copy link
Member

@kevinsmith, you must provide the decoded json data, not the json string. There is a warning in the documentation about this https://docs.opis.io/json-schema/1.x/php-validator.html#validation-methods

$data = '{"sample":"request_body"}'; // raw json data as string
$data = json_decode($data); // decode the json data
$validator->schemaValidation($data, $schema); // now we can validate

@kevinsmith
Copy link
Author

Sorry, that was an error I made in trying to oversimplify the example. In my actual code I'm taking the request body (a JSON string) and running it through json_decode(). I updated the example above to reflect that.

@sorinsarca
Copy link
Member

Ok, I've just tried to reproduce your issue and I couldn't.
If the code don't throw any exception can you post the validation result (or the exception otherwise)?

Please use the specified input.

$data = '{"name": "My name", "email": "[email protected]"}';
$data = json_decode($data);
$result = $validator->schemaValidation($data, $schema);
var_dump($result);

@kevinsmith
Copy link
Author

Well, I think this might be entirely a misunderstanding on my part! My apologies! With JSON that looks like

{"name": "My name"}

I get an error that the required attribute "email" is missing, and I can see that Validator::validateRef() never gets called at all. With the JSON

{"name": "My name", "email": "thisisnotavalidemail"}

I get a pattern validation error, which would be expected, and I can see that Validator::validateRef() does get called.

So I guess I was expecting the entire document would be resolved before any validation would be run. It appears that it's actually lazy-loading references to avoid making any unnecessary calls. Do I have that right?

This raises another question though. I've noticed that if I try to validate the JSON

{}

or

{"email": "thisisnotavalidemail"}

There's only 1 error, and it's that "name" is missing. "email" is never validated, either to be sure it's there or to check that it matches the pattern. Is the validator meant to only return the first error? That's not what I would've expected given that it includes methods like https://docs.opis.io/json-schema/1.x/php-validation-result.html#totalerrors

@sorinsarca
Copy link
Member

So I guess I was expecting the entire document would be resolved before any validation would be run. It appears that it's actually lazy-loading references to avoid making any unnecessary calls. Do I have that right?

Yes, the documents are loaded only when needed.

Is the validator meant to only return the first error?

Well, there is a third param to schemaValidation(), dataValidation() and uriValidation() called $max_errors where you can set the max errors. Currently this means that the validation will continue until max errors are reached. I'm guessing that you are trying to validate a form and show all error messages and that's why you need multiple errors. However, it is possible that later you might encounter another issues because the behaviour of max errors is a little bit inconsistent. If this is the case please check #16 and related issues.

The good news is that in version 2.0 we will have consistent support for max errors and error messages. Currently I'm working on the documentation for version 2.0 and I hope that this month it will be released.

@kevinsmith
Copy link
Author

Sounds good, thanks!

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