Closed Akron closed 6 years ago
Sorry for submitting an example app again instead of doing a pull request
Not a problem. When using TEST_YANCY_BACKEND
, did your myfile.db
have the schema written (from t/share/sqlite.sql
)? Without that, the tests won't work: They don't know how to set up a schema. I should add some docs in CONTRIBUTING about running the integration tests, and where all the various tests are (like how backend tests are actually in t/lib/Local/Test.pm
).
As for your problem: It seems like the solution to this is to allow the email
field to be null
, by setting multiple types:
plugin Yancy => {
backend => {
sqlite => app->sqlite
},
collections => {
people => {
required => ['name'],
'x-list-columns' => [qw/name/], # No difference though
type => 'object',
properties => {
id => {
type => 'integer',
readOnly => 1,
},
name => {
type => 'string'
},
email => {
type => [ 'string', 'null' ] # Can be a string, or since it is not required, null
}
},
example => {
name => 'Philip J. Fry'
}
},
}
};
This should be picked up automatically if using read_schema => 1
:
plugin Yancy => {
backend => {
sqlite => app->sqlite
},
read_schema => 1, # Fill in the parts we don't define below
collections => {
people => {
'x-list-columns' => [qw/name/], # No difference though
example => {
name => 'Philip J. Fry'
}
},
}
};
But, it's an annoying problem, and I got bit by it a few times myself, so I'm going to add a DIAGNOSTICS
section to the config help document about this problem of Expected <type> - got null.
and its solution. And possibly a section called Nullable Fields
to make it really obvious what's going on.
I could also add some sanity checks to the config: A command or a startup check to see if there are problematic type differences between the schema as it is (read_schema
) and the configuration. If there are conflicts, write a warning to the log.
What do you think would have been most helpful when you came across this problem?
The underlying problem is that the JSON schema sees the email
field and checks its type. It sees that it's not one of the allowed types and throws an error.
Another alternative to solve this problem could be for the backend, or the API controller, to explicitly remove any fields whose value is null
: Unless the field is required by the required
list of fields, it's optional and does not have to be defined.
I'm not sure I like that idea: It makes it more difficult to loop over all the fields in a collection when you only have an item of the collection. But, this solution would have the benefit of not requiring users to configure explicitly null fields, removing this problem entirely. And it'd only have to be in the API controller, everywhere else could get the rows exactly as they are.
Thoughts / Opinions?
Alright. I went with the API controller changes so that the configuration doesn't have to change. The editor already goes through and prunes out null
values when adding/editing items, so this is just the other side of that: The API controller serves the editor the same thing the editor would send back.
I also added some docs for using ./share/run_backend_tests.pl
, which should help with running the integration tests, and some docs about the error you came across if someone later comes across it again (it's a misconfiguration in any case, it's just more difficult to reach now).
The config vs. schema sanity check would still be a pretty awesome feature, but it's something that can be done later.
Thanks for taking the time to try things out and write up these detailed bug reports. I really appreciate the help!
Thank you very much! That did indead the trick!
Sorry for submitting an example app again instead of doing a pull request
Not a problem. When using TEST_YANCY_BACKEND, did your myfile.db have the schema written (from t/share/sqlite.sql)?
Ah - no, sorry. I didn't know that and I thought that there were various different schemas involved in testing so the individual tests would do the setup.
What do you think would have been most helpful when you came across this problem?
I wouldn't have considered null
to be a type - so that was the main source of confusion to me, I guess.
I also didn't know that it's valid to set multiple types, but I probably missed that in the documentation.
I'm not sure I like that idea: It makes it more difficult to loop over all the fields in a collection when you only have an item of the collection.
Yes, I now see the problem as well. On the other hand, it ensures the data to be sparse, in case the majority of fields are optional and unset. I would have preferred your solution as well (mainly because of the "null as a type" confusion).
What do you think would have been most helpful when you came across this problem?
I wouldn't have considered null to be a type - so that was the main source of confusion to me, I guess. I also didn't know that it's valid to set multiple types, but I probably missed that in the documentation.
It wasn't in the docs, and was merely implied by pointing at JSON Schema's docs. It's funny that you mention that, because now I'm remembering that I also did not know that when I came across the error you did, and had to read the JSON Schema docs to find it out ;). Now there's an explicit reference to it in Yancy's docs, so that should help as well. We'll find out when the next patsy ... I mean person... tries Yancy out ;)
When listing a collection with optional unset fields, in SQLite the backend responds with
There is no difference, whether the field is a listed column or not. Tested with: 1.001 Example app:
(Sorry for submitting an example app again instead of doing a pull request, but I wasn't able to find a backend specific full integration test in the test suite and had no luck using
TEST_YANCY_BACKEND="sqlite:myfile.db" prove -lr t/
).