RepreZen / KaiZen-OpenApi-Parser

High-performance Parser, Validator, and Java Object Model for OpenAPI 3.x
130 stars 31 forks source link

Resolution of references #149

Closed gervaisb closed 6 years ago

gervaisb commented 6 years ago

I should have missed the point, but once I have a com.reprezen.kaizen.oasparser.jsonoverlay.Reference, how can I de-reference it to get back a com.reprezen.kaizen.oasparser.model3.Schema ?

andylowry commented 6 years ago

Thanks @gervaisb. That's actually not something that occurred to me when designing the current scheme, so the short answer is that you can't.

Since the generated API navigates through references automatically by default, my focus was on making it possible to find out reference information when it was there. But I can definitely see the benefit of making the overlay object to which a Reference object is associated available (as a generic JsonOverlay<?>, which would then need to be cast).

I'll probably try to do this as part of #119, which will change the way References are obtained - as well as many other generic overlay operations - so as to stop cluttering the generated API with methods like getXxxReference() etc. It will also mean that this will be available for all overlays, not just the ones that are marked as "refable" in the types specification. That limitation was a compromise to reduce clutter in the API. I expect the new approach to look more like Overlay.of(value).getXxxReference().

gervaisb commented 6 years ago

What do you mean by "the generated API navigates through references automatically" ? My goal is to generate classes from the OpenApi schema. I'm looping inside all schemas but it there is another way of doing it I will be happy to know it.

Otherwise I plan to extract the schema name from his reference path..

andylowry commented 6 years ago

@gervaisb What I meant was that any way you can navigate through the API to get a schema, you'll get the Schema object, regardless of whether there were any references along the way. You'll only know if something was a reference if you use, e.g. the isSchemaReference(name) or getSchemaReference(name) method at the point where you've got a schema.

As for knowing the name of a schema, you can do schema.getPathInParent(). This is a general method that provides, for any object, the path that would get you from the parent object to this object. For objects that are built from properties of a JSON "object" value, that's the property name.

Keep in mind that for a schema that's obtained by reference, its parent means the object that actually contains the schema definition, not anything that specifies the schema by reference. Typically, that will be the /components/schemas JSON object. But it's entirely possible for a schema to be inlined, e.g. in a Media Type object. In that case, its pathInParent will be schema since that's the name of the Media Type object property that leads to the inlined schema. Such a schema is really essentially unnamed.

gervaisb commented 6 years ago

Okay, thanks, Schema#getPathInParent():String does the trick.

With this extract:

 Pets:
      type: array
      items:
        $ref: "#/components/schemas/Pet"

And given that schema is "Pets", then schema.getItemsSchema().getPathInParent() returns "Pet", that perfect to me. :+1: