-
-
Notifications
You must be signed in to change notification settings - Fork 958
feat(jsonschema): make JSON-LD specific properties required only in the schema for output #6485
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
Conversation
477251a to
6f19dbb
Compare
|
@soyuka /cc @paullallier We still need to discuss the following points:
|
822e132 to
334db2e
Compare
…for JSON-LD specific properties
334db2e to
a42ca67
Compare
|
Thanks @ttskch. I'm not going to claim to know much about the strict requirements of the OpenApi spec and I'm primarily interested in having a functional API for my project. I suspect the previous iteration of the fix actually didn't break my API itself, just the That's not to say we shouldn't bother trying to be consistent with the OpenApi spec. I think you're likely to be correct that, generally, for an entity with an embedded array of subresources (say a "Course" entity was an array of "Student" entities enrolled on that course) - the subresources should have an @id, because you can get the details of a single student. Probably should have an @context too, though I don't know whether it MUST. My use case is different from this though. For example, I have an "Invoice" entity with an array of "InvoiceLine" entities embedded into it. In that case, it's not desirable to me that someone should be able to GET one of the InvoiceLine entities in isolation from the Invoice and I haven't made an endpoint to get them. I'm using A side note, I did also get some failures when checking the schema on errors (which might have been a mistake on my part anyway - but it was passing before). We should potentially check that the problem objects are correctly including @context if that's really needed. |
|
Thank you for the detailed explanation @paullallier. /cc @soyuka I've created a simple reproduction environment for this issue below. https://github.com/ttskch/api-platform-core-6485
In this situation, I created a simple test using With a42ca67, this test fails as you say. But after applying the fix in 23af961, this test passes. From my understanding, in the schema for sub-resources, In What do you guys think? Thanks. |
|
Thanks for your work @ttskch! I was on holiday and I'll take time to see how everything fits here, I'll come back to that asap. |
|
So, the main issue here is that we multiply the JSON Schemas for a given resource which is really heavy work for no much gain. I don't have much time (as 3.4/4.0 release is planned for September I have a lot of work right now), but we need to read the JSON schema specification (https://json-schema.org/draft/2020-12/json-schema-core) as I'm sure that there's a way to reference the JSON-LD specific fields. If there's none, I think that it's acceptable to have optional properties for special fields (@id, @type, @context etc.) eventhough they're required on output. WDYT @vincentchalamon ? |
|
We need to use |
|
should be fixed in 4.2 |
In JSON Schema for JSON-LD, following things are the truth:
@context@id@typecan be included in the request body. (See fix(jsonld): allow @id, @context and @type on denormalization 2 #6451)@context@id@typealways have a value in the response body. (In other words, they are required.)Therefore, this PR will make the following fixes:
@context@id@typenon-readOnly.@context@id@typerequired.Below is a simple example.
Currently, the following schema is generated for the above API resource.
This schema is clearly incorrect because:
@context@id@typecan be included in the request body. (See fix(jsonld): allow @id, @context and @type on denormalization 2 #6451) So the must not be readOnly.@context@id@typealways have a value in the response body. (In other words, they are required in the output context.)JSON-LD specific properties such as
@context@id@typeshould be output as required in the OpenAPI document. However, since the above schema is shared by both the request body and response body, if we set these properties to required, they will also be required in the request body.The fundamental problem is that the above schema is shared by both the request body and response body. In the first place, in the current implementation, even though
ApiPlatform\Hydra\JsonSchema\SchemaFactorydoes not add JSON-LD specific properties in theinputcontext, the schemas for input and output are generated with the same key, so the same schema is shared between the input and output contexts. This is clearly a bug.Therefore, in this PR, I first modified the schemas for input and output to be generated with different keys.
And I also made JSON-LD specific properties such as
@context@id@typenon-readOnly (because they can be included in the request body) and made those properties required only in the schema for output (if those properties exist).This ensures that JSON-LD specific properties are not required in the request body, and those properties are marked as required in the response body.
This has the advantage that the type information of API clients automatically generated by OpenAPI TypeScript etc. will be more precise.
export interface operations { api_todos_post: { requestBody: { - "application/ld+json": components["schemas"]["Todo.jsonld"]; + "application/ld+json": components["schemas"]["Todo.jsonld.input"]; }; responses: { 201: { content: { - "application/ld+json": compoennts["schemas"]["Todo.jsonld"]; + "application/ld+json": compoennts["schemas"]["Todo.jsonld.output"]; }; }; }; }; }; export interface components { schemas: { + "Todo.jsonld.input": { + "@context"?: string | { + "@vocab": string; + /** @enum {string} */ + hydra: "http://www.w3.org/ns/hydra/core#"; + [key: string]: unknown; + }; + "@id"?: string; + "@type"?: string; + readonly id?: number; + title: string; + description?: string | null; + done: boolean; + }; - "Todo.jsonld": { + "Todo.jsonld.output": { - readonly "@context"?: string | { + "@context": string | { "@vocab": string; /** @enum {string} */ hydra: "http://www.w3.org/ns/hydra/core#"; [key: string]: unknown; }; - readonly "@id"?: string; + "@id": string; - readonly "@type"?: string; + "@type": string; readonly id?: number; title: string; description?: string | null; done: boolean; }; }; };