The Spring framework provides a couple of generic classes to support the HATEOAS 'constraint' of the REST application architecture. We used SpringFox to generate the JSON definition of our service that uses the Resource and PagedResource generics provided by Spring HATEOAS. The generic references appear in the JSON file in a modified form such as: PagedResources«Resource«MyStuff»» but the JAVA client code generation flattens the generic references so that PagedResources«Resource«MyStuff»» becomes PagedResourcesResourceMyStuff.
The JAVA client must build its own logic to get the content from these flattened references instead of being able to use the mechanisms provide by the Spring Framework.
My suggestion is to add a step in the code generation (probably after the templates are applied) that turns references such as PagedResourcesResourceMyStuff back into PagedResources<Resource<MyStuff>>.
swagger-codegen-cli 2.2.3
java -jar swagger-codegen-cli-2.2.3.jar generate -l java --library resttemplate -i service.json -t resttemplate -o api
https://github.com/springfox/springfox/issues/746 - not really resolved
I have forked swagger-codegen and proposed a solution at https://github.com/bzylstra/swagger-codegen/tree/hateoas_generics.
Expand Resource and PagedResources generics for Java Rest
- add new hook to codegen config: postProcessFileContents that is invoked after the file contents are generated from the template but before they are written to the file. Default is to leave contents as found
- for java client code generator, if the library is resttemplate and template is for the api, expand all occurrences of PagedResourcesBlah into PagedResources<Blah> and ResourceBlah into Resource<Blah>
I don't think you should use swagger/OpenAPI together with HATEOAS. Swagger is meant to describe an API that has a fixed structure whereas HATEOAS aims at dynamic interfaces with auto-discovery.
Our API has a fixed structure - the payload uses Resource and PagedResources to provide links to other resources. For example, the Employee can have have direct reports that are other employees and that can be represented as a collection of links. The API is fixed - the query always returns an Employee but the Employee can include references to other Employees.
Swagger has been an excellent fit with the exception of the limitation on generics.
To me your issue is with Springfox as the generated swagger looks wrong. Can you check your Springfox config ? Did you use their Spring-data-rest plugin ?
SpringFox rendered the the generics reference as per its documentation: http://springfox.github.io/springfox/docs/current/#changing-how-generic-types-are-named
I see in the JSON file:
"responses": {
"200": {
"description": "OK",
"schema": {
"$ref": "#/definitions/PagedResources«Resource«EmployeeInfo»»"
}
},
Note that I also tried tweaking the JSON file to use <> instead of «» but the output of the codegen for the JAVA client on the resttemplate library was the same:
public PagedResourcesResourceEmployeeInfo getAllEmployeesUsingGET() throws RestClientException
The desired output is:
public PagedResources<Resource<EmployeeInfo>> getAllEmployeesUsingGET() throws RestClientException
Is there a variant of the JSON file that would cause the codegen to produce the desired output? I have not found it. If there is, I will gladly take up the issue with the SpringFox team.
Any update on this issue?
@cbornet this is a pretty standard thing nowadays with spring boot + spring fox
@bzylstra did you found a workaround?
We had forked for a time but then switched to DOTNET and it was no longer an issue.
Most helpful comment
SpringFox rendered the the generics reference as per its documentation: http://springfox.github.io/springfox/docs/current/#changing-how-generic-types-are-named
I see in the JSON file:
Note that I also tried tweaking the JSON file to use <> instead of «» but the output of the codegen for the JAVA client on the resttemplate library was the same:
The desired output is:
Is there a variant of the JSON file that would cause the codegen to produce the desired output? I have not found it. If there is, I will gladly take up the issue with the SpringFox team.