Hi, currently I am using spring HATEOAS 1.0.1.RELEASE with spring-boot 2.2.1.RELEASE and springdoc-openapi-webmvc-core version 1.2.17. I saw that the project shows it support HATEOAS now but in swagger, I still see the example value show all the fields of EntityModel instead of the response we will get. Is there anything I need to config for that
Example value:
{
"id": "string",
"links": [
{
"rel": "string",
"href": "string",
"hreflang": "string",
"media": "string",
"title": "string",
"type": "string",
"deprecation": "string",
"profile": "string",
"name": "string"
}
]
}
Response thing:
{
"id": "test-id",
"_links": {
"self": {
"href": "http://localhost:8374/my-path"
}
}
}
Hi,
The support has been addded based on the original issue feedback: #169
The sample value is based on the EntityModel structure.
If you expect another structure, please provide more details about how do expect this object to be mapped, and we will be happy to address it.
Hi,
As @kingtran2112 is pointing out, there is a mismatch between the generated documentation (based on EntityModel) and the actual JSON representations. If you are relying on the OpenAPI specification for customers and you are using Spring HATEOAS, this is not desirable.
I would expect links and embedded to follow the HAL specification draft (link), i.e. _links and _embedded. Furthermore, I would expect the structure within these sections to reflect the actual response representations rather than being based on the EntityModel structure.
Where are we on this?
I moved from SpringFox to openapi due to lack of HATEOAS support in SpringFox and I didn't want to use the SNAPSHOT version (which almost works). But I can't get it to work at all in openapi.
I'm using
spring-boot 2.2.6.RELEASE
springdoc-openapi 1.4.3
I have the following maven dependencies
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>${springdoc-openapi-version}</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-hateoas</artifactId>
<version>${springdoc-openapi-version}</version>
</dependency>
The following code generates the output as expected
CaseService.createCase(theRequest);
Link theCaseLink =
linkTo(methodOn(CaseController.class).getCase(null, theUniqueKey))
.withSelfRel();
RepresentationModel<?> theCaseRepresentation =
new RepresentationModel<>(theCaseLink);
ResponseEntity<RepresentationModel<?>> theResponse =
new ResponseEntity<>(theCaseRepresentation, HttpStatus.CREATED);
return theResponse;
The response is
{
"_links": {
"self": {
"href": "http://localhost:8080/cases/id/unique-key/abc"
}
}
}
But the documentation is completely off
{
"_links": {
"additionalProp1": {
"href": "string",
"hreflang": "string",
"title": "string",
"type": "string",
"deprecation": "string",
"profile": "string",
"name": "string",
"templated": true
},
"additionalProp2": {
"href": "string",
"hreflang": "string",
"title": "string",
"type": "string",
"deprecation": "string",
"profile": "string",
"name": "string",
"templated": true
},
"additionalProp3": {
"href": "string",
"hreflang": "string",
"title": "string",
"type": "string",
"deprecation": "string",
"profile": "string",
"name": "string",
"templated": true
}
}
}
I have no idea where prop2 and prop3 are coming from. But the link component in the schema is
Link {
hreflang | string
title | string
type | string
deprecation | string
profile | string
name | string
templated | boolean
}
What do I have to do, to get the documentation correct?
@milindrao,
The OpenAPI documentation is available on the endpoint /v3/api-docs. And this is what is generated by springdoc-openapi.
You are not reporting anything wrong about the generated OpenAPI ...
The prop2/prop3 are automatic examples generated by the swagger-ui, when examples are not filled depending on the types.
This the swagger-ui default behaviour and not a springdoc-openapi one;
If you want to change adapt the examples, you use can use OpenApiCustomiser to attach the example you want to display.
Thanks. I fixed it by doing the following.
Declare a CaseHrefRepresentation class
@SuppressWarnings("rawtypes")
@Schema (example = "{\"_links\": {\"self\": {\"href\": \"http://<domain:port>/cases/id/unique-key/case_id\"}}}")
class CaseHrefRepresentation extends RepresentationModel {}
In the method definition, use the class in the schema
@Operation(summary = "Creates and saves a case.",
responses = {
@ApiResponse(responseCode = "201", description = "Created", content = @Content(schema = @Schema(implementation = CaseHrefRepresentation.class))),
@ApiResponse(responseCode = "401", description = "Unauthorized", content = @Content),
})
@ResponseStatus(HttpStatus.CREATED) // Needed to prevent the creation of HttpStatus.OK in swagger.
@PostMapping(value = "/cases",
produces = {application/hal+json},
consumes = {MediaType.APPLICATION_JSON_VALUE})
public ResponseEntity<RepresentationModel<?>> createCase(
I'm sure there's a better more correct way to do this. But for now, it works for me.
Most helpful comment
Hi,
As @kingtran2112 is pointing out, there is a mismatch between the generated documentation (based on EntityModel) and the actual JSON representations. If you are relying on the OpenAPI specification for customers and you are using Spring HATEOAS, this is not desirable.
I would expect
linksandembeddedto follow the HAL specification draft (link), i.e._linksand_embedded. Furthermore, I would expect the structure within these sections to reflect the actual response representations rather than being based on the EntityModel structure.