Open innokenty opened 3 years ago
Well it's probably not a bug, but I'm not sure what it is. I think it should be tackled though.
This is because the implementation used by the problem-detail library, has StatusType in the POJO, and registers a Jackson-Module to the ObjectMapper, that provides code to serialize the StatusType class to ensure the serialized output is an integer. The code that builds the model in Swagger (ModelResolver), however, tries to makes its own interpretation of the Problem class. Since the Module contains serialization code, and not any declarative config/metadata, it doesn't take into account how that object is serialized by Jackson's ObjectMapper.
I'm not sure what the solution is though, other than it needs to take into account all the information Jackson has.
It would have to analyze the Jackson-configuration, find which classes are serialized differently, and account for that in the model. Alternatively, the ModelResolver could instead populate and serialize a dummy object, analyze the resulting json and try to make a model based on that, or at least see where the json differs from its current model.
Edit: The ModelResolver method "resolve()" that does the interpretation, is 750 (!) lines long, and thus very hard to understand.
Exactly. And I think this is the only place that's different, so I think the best solution would be to make the model same as json. Maybe there is a reason though, why it was made different..
I was thinking the same, maybe the reason for this is on a higher level. Perhaps swagger wants to serialize everything "raw" and not be modelled differently as an application grows with more registered modules on how to serialize such that you maintain the integrity of your contracts - this is pure speculation though.
This might be more of a question for swagger than zalando perhaps.
The biggest technical issue here is that without a declarative description of the serialization rules in the POJO or in the Jackson-Module/ObjectMapper, it's very hard to deduce what the actual output is. It could be possible to pick up the serialization functions, but the output is either Object or String, so you won't know what type it actually is.
A hacky way to figure it out, could be to populate each field in the POJO with a value describing the type of the field, then serializing the object and then mapping back from the string-values on each json property to a type, for use in the model.
so I think the best solution would be to make the model same as json. Maybe there is a reason though, why it was made different..
In a nutshell: https://whiskeysierra.github.io/knowledge/primitive-obsession/
The code that builds the model in Swagger (ModelResolver), however, tries to makes its own interpretation of the Problem class. Since the Module contains serialization code, and not any declarative config/metadata, it doesn't take into account how that object is serialized by Jackson's ObjectMapper.
That approach is flawed by design, because it can't possibly detect cases that aren't defined in a declarative way. The use of an imperative converter (a feature that Jackson supports out of the box) breaks it.
It could be possible to pick up the serialization functions, but the output is either Object or String, so you won't know what type it actually is.
Yes, that would actually be a) easier to implement, b) simpler in design and c) more robust. (Also probably a bit slower, but someone would need to benchmark that.)
Zalando follows an API first principle which contradicts the usage of tools that annotate code and generate the API from that. You shouldn't expect any support here. If you're willing to put time into this and you find a solution that is acceptable in terms of maintenance over time, I'm sure there would be a way to get that in.
So I'm trying to generate the swagger API from code with swagger annotations. It all works well except
Problem.statusType
field.Description
I am describing my endpoint's responses like this:
But because
Problem.statusType
field is not an integer as per API specification, but a class – the generated swagger output is wrong.Expected Behavior
The following component are generated for swagger yaml:
Actual Behavior
The following components are generated for swagger yaml:
Possible Fix
Do you think this can be fixed at the library level? Or should I create a bug in problem spring web adapter better?