Open seveneves opened 2 weeks ago
Sure this sounds like something we should support, do you maybe have some pointer as to when $defs
should be used, comparing to #/components/schemas/
? So that we follow the spec
Also cc @ghik
Yes, the comparator is limited in many ways and generally optimized for schemas generated from tapir endpoints. $def
is not understood at all. More details in the PR: https://github.com/softwaremill/sttp-apispec/pull/157
@adamw it is a good question.
Looking at the latest specification of json schema, $ref
can have multiple ways of referring to a schema, the one which is missing is called Schema with a JSON Pointer
and the format is { "$ref": "#/$defs/string" }
.
Such reference is defined here https://github.com/softwaremill/tapir/blob/91a95b77009ed887fea9407eb8f8f6948e8984c6/docs/apispec-docs/src/main/scala/sttp/tapir/docs/apispec/schema/TapirSchemaToJsonSchema.scala#L20
$def is not understood at all
@ghik This is what I also noticed :)
But it is relatively easy to support it. If it is done then TapirSchemaToJsonSchema
can be used to generate apispec.Schema
and such schemas could be used in SchemaComparator
.
I have it working on my machine without major changes to the comparator but I had to refactor the resolution/normatlization logic
If it's a simple change - why not, but I suspect there must be some difference between references using $ref
+ $def
and #/components/schemas/
?
That is, when should one be used, and when the other?
@adamw I believe $defs
is a feature of JSON Schema (in isolation), while #/components/schemas
is an OpenAPI specific thing. For this reason I assumed that there shouldn't be much reason to use $defs
in schemas generated from tapir endpoints, as they can use the components
object as the library for reusable schemas.
Oh, it seems my assumption was somewhat subconscious and, in fact, not a right one, looking at this code which uses $defs
.
IMO it would still be more natural to use #/components/schemas
for that, but I might be missing some context.
@ghik I think you're right, $def
s allows you to reuse schemas within a single JSON schema, that is in the context of OpenAPI in within a single body definition, for example. While components/schemas
allows you to reuse schemas across different json schemas, for different bodies.
In the tapir schema -> json schema conversion, we cannot use the shared pool (as it doesn't exist in that context), so we're using $def
s.
Anyway, seems that supporting $def
s in the same way as supporting components/schemas
seems the way to go, so @seveneves if you'd like to contribute that change, that would be great :)
I am using
SchemaComparator
to check that there are no compatibility issues between two version of the same json schema, which is decoded asapispec.Schema
.Following program highlights the problem
And to avoid the problem specified in #170, I reset
$schema
and$defs
and pass$defs
as arguments tonew SchemaComparator
.Such comparison does not identify new field
age: Int
inv2.Child
schema, which it should detect.The reason for this is that there is no
$ref
lookup implemented for#/$defs/
and it only supports#/components/schemas/
.After playing around with code of
SchemaComparator
and addingDefsRef
along withLocalRef
, I was able to make it work and produce the desired validation checkI can submit a PR to fix this and #170 but I need a reaction from the maintainer to validate both issues.