restdocs-api-spec
restdocs-api-spec copied to clipboard
support for $ref
Hi,
I am trying to use rest-docs / restdocs-api-spec to generate the openapi spec for these two endpoints :
the first endpoint returns a list of Driver and the second one just one driver. I didn't found yet a way to document that on my unit test.
So, for now, the generated spec contains, in components/schema, a Driver structure and another structure that represents a list of Driver, but on these two structures, the duplication of code is important :
Is there a way to document things so that something like the following will be generated?
Hey @alexisparis ,
yeah, the schema generation isn't smart enough for this use-case, yet.
Would you mind posting the resource.json
snippet for each of the two examples, please?
How restdocs-api-spec generates a JSON schema
The common brain is in here:
https://github.com/ePages-de/restdocs-api-spec/blob/master/restdocs-api-spec-jsonschema/src/main/kotlin/com/epages/restdocs/apispec/jsonschema/JsonSchemaFromFieldDescriptorsGenerator.kt#L28
(tests: https://github.com/ePages-de/restdocs-api-spec/blob/master/restdocs-api-spec-jsonschema/src/test/kotlin/com/epages/restdocs/apispec/jsonschema/JsonSchemaFromFieldDescriptorsGeneratorTest.kt )
which produces a JSON schema string which is then parsed in the OpenAPI 2, 3 generators to produce the respective schemas (Model
type for OpenAPI 2/Swagger 1.5, Schema
type for OpenAPI 3), e.g.:
https://github.com/ePages-de/restdocs-api-spec/blob/master/restdocs-api-spec-openapi-generator/src/main/kotlin/com/epages/restdocs/apispec/openapi2/OpenApi20Generator.kt#L461
https://github.com/ePages-de/restdocs-api-spec/blob/master/restdocs-api-spec-openapi3-generator/src/main/kotlin/com/epages/restdocs/apispec/openapi3/OpenApi3Generator.kt#L371
Roughly speaking, two payloads produce the same JSON schema, if both are of the same content type and use the same set of FieldDescriptors (two descriptors considered the same, if they document the same JSON path).
In the generators we then keep a cache of JSON schemas (map with Model
/Schema
types as key) and reuse a schema if some payload produces the same Model
/Schema
(using the equality defined by those upstream classes of the Swagger project).
Notice how this isn't attempting in finding common reusable sub-structures.
So far, it mostly works for when request and response payloads match (common resource) and thus the same set of FieldDescriptors apply, producing the same schema, which is then defined once and referenced for both cases.
The only "smartness" I see there right now, is type unification (two FieldDescriptors for same path, but with different types, produce a schema for a single field supporting the union of both types).
The reason I'm asking for your resource.json
snippets is, that maybe we could try to use subsectionWithPath
or some prefix for the array and then have a common set of descriptors (all with same paths) across both responses, which might produce the same schema (I'm uncertain here, but prob. worth a try).
@ozscheyge thank you for your support resource-get-driver.log resource-get-drivers.log
Okay, the produced resource.json files confirm my assumption:
Single resource:
"path" : "dangerous",
Collection resource:
"path" : "[]dangerous",
etc. So, as explained above, the basic algorithm to form the schema from the FieldDescriptors does not detect that those paths may describe the same object.
Hi @ozscheyge I made some tries with subsectionWithPath but was not able to generate spec as expected. Is there a way to provide a reference type? Do you know how subsectionWithPath should be used in that case?
Hi @ozscheyge I made some tries with subsectionWithPath but was not able to generate spec as expected. Is there a way to provide a reference type? Do you know how subsectionWithPath should be used in that case?
Hey, the subsectionWithPath
-suggestion was just an ad-hoc idea, seems like it didn't work. :|
I'm afraid, this issue isn't supported by restdocs-api-spec, yet.
@ozscheyge Hi, I also need this part. If I get a chance in the future, can I modify the code a bit to utilize 'AbstractDescriptor.attributes()' and submit a pull request? I don't think it would be a small cost to work on this part, and furthermore, I don't think using 'AbstractDescriptor.attributes()' would be the right way to do it, so I need consent.
Hey @xeromank ,
what would be the right way to do this, in your opinion? Could you outline, how you would solve this using AbstractDescriptor.attributes()
, please?