Skip to content
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

Unable to Get Array Items' Ref #234

Open
dillonredding opened this issue Apr 2, 2019 · 9 comments
Open

Unable to Get Array Items' Ref #234

dillonredding opened this issue Apr 2, 2019 · 9 comments

Comments

@dillonredding
Copy link

Perhaps I'm missing something, but I can't seem to get the reference of an array's items.

Given the spec:

openapi: 3.0.2
# ...
components:
  schemas:
    event:
      type: object
      properties:
        invitees:
          type: array
          items:
            $ref: '#/components/schemas/user'
    user:
      type: object
      properties:
        name:
          type: string

This returns false:

Overlay.of(model.getSchema("event").getProperty("invitees")).isReference("items");
@tedepstein
Copy link
Contributor

@dillonredding , that behavior definitely looks wrong, not consistent with what's described in our docs here.

How are you parsing the model? From a string, a file, URI or URL? Is there anything between the parse and the isReference call that could account for loss of reference information?

FYI, we will most likely not have bandwidth on the RepreZen team to look at this for a while. If you are inclined to dig into the code yourself and try to find the root cause of this, we'd appreciate the help. If not, I'm sorry we couldn't turn around a quick fix or a better explanation at this time.

@dillonredding
Copy link
Author

I'm reading it from a file. I tried removing any intermediary processing with the following example, but still get the same result.

var resource = this.getClass().getResource("/api-spec.yaml");
var file = new File(resource.getFile());
var model = new OpenApi3Parser().parse(file);
var property = model.getSchema("event").getProperty("invitees");
assertFalse(Overlay.of(property).isReference("items"));

@dillonredding
Copy link
Author

I get the same parsing as a string

var resource = this.getClass().getResource("/api-spec.yaml");
val contents = Files.readString(Paths.get(resource.toURI()));
var model = new OpenApi3Parser().parse(contents);
// ...

a URI

var resource = this.getClass().getResource("/api-spec.yaml");
var model = new OpenApi3Parser().parse(resource.toURI());
// ...

and a URL

var resource = this.getClass().getResource("/api-spec.yaml");
var model = new OpenApi3Parser().parse(resource.toURI().toURL());
// ...

I might be able to take a stab at digging into the code.

@dillonredding
Copy link
Author

This issue appears to be in Overlay#getReference(String):

public Reference getReference(String key) {
    if (overlay instanceof PropertiesOverlay) {
        return getPropertyReference(key);
    } else if (overlay instanceof MapOverlay) {
        return getMapReference(key);
    } else {
        return null;
    }
}

In my case, Overlay.of(model.getSchema("event").getProperty("invitees")) returns an Overlay<Schema>, meaning the overlay field is an instance of SchemaImpl. Therefore, calling getReference returns null, causing isReference to return false.

I'll keep digging and try to figure out a fix. Until then, any recommendations, @tedepstein?

@tedepstein
Copy link
Contributor

@dillonredding , many of the classes are generated by JSON Overlay; and there aren't any docs available on that project yet. I don't really have intimate knowledge of this code, and don't have capacity on the development team right now to look at this.

I've been digging into it for a while now, just trying to get my head around it. I was hoping to find a recent change that might account for the breakage, because this seems like the kind of thing that "must have worked at some point." Subschemas, like the items subschema you've referenced in your input, are a very common thing to represent using $ref.

Seeing that this is not working in your case would seem to mean either:

  1. Your code is not doing this right, which also means that our docs are wrong. I'm sorry to say, but I really wouldn't be in a position to know if this is the case.

  2. Something is fundamentally broken in JSON Overlay and/or KaiZen Parser, which seems unlikely because it's working in our projects.

  3. Something is locally broken in this particular case, but we don't know why. Seems the most likely case, I just don't have bandwidth at this moment to research it completely.

Again, sorry that I cannot be of more immediate help. We'll get to it as soon as we can.

@tedepstein
Copy link
Contributor

@dillonredding , just a quick question: Why do you need to inspect the $ref?

I imagine you have a good reason. But in my earlier research, it looked like most of our use cases lean pretty heavily on automatic resolution of refs, and then don't care about the original $ref value, only the resolved object graph.

I don't have high confidence in this theory, because I haven't looked comprehensively at all of our code that uses KaiZen Parser. But if this is largely correct, that might explain why something that seems pretty fundamental is broken, and has been for some time. And then we can feel a little more comfortable just pushing forward with a fix.

@dillonredding
Copy link
Author

@tedepstein, I'm creating a Maven plugin that will generate Java classes based on the schemas in an OpenAPI spec. In the case of an array property, the field would be a List and I'd like to inspect the $ref for generating the type parameter.

In my original example, you'd get a class for the user schema

// package and imports...

public class User {
   private String name;

   // getters, setters, toString, etc...
}

And the class for the event schema would look something like

public class Event {
   private List<User> invitees;
}

If the items aren't a reference and, say, of type string, then you'd get a List<String>.

@ghost
Copy link

ghost commented Nov 13, 2020

@dillonredding I am doing a similar code generation tool to what you referred to above. Did you ever solve this issue?

@dillonredding
Copy link
Author

@pconrey No, I eventually dropped this effort since it ultimately contradicted some fundamental principles of REST architecture

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants