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

Unexpected fields in request body definition for RepresentationModel DTO (HATEOAS) #725

Closed
Flightkick opened this issue Jun 10, 2020 · 1 comment
Labels
bug Something isn't working

Comments

@Flightkick
Copy link

Describe the bug
I'm using HATEOAS and the generated request body seems wrong. Both the RequestBody and the ResponseBody contain additionalProp* fields in the _links field.

RequestBody according to Swagger UI: POST /company

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "name": "string",
  "_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
    }
  }
}

ResponseBody according to Swagger UI: POST /company

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "name": "string",
  "_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
    }
  }
}

To Reproduce
Steps to reproduce the behavior:

  • What version of spring-boot you are using?
    2.3.0.RELEASE
  • What modules and versions of springdoc-openapi are you using?
    'org.springdoc:springdoc-openapi-ui:1.4.1'
    'org.springdoc:springdoc-openapi-data-rest:1.4.1'
    'org.springframework.data:spring-data-rest-webmvc:3.3.0.RELEASE'
  • What is the actual and the expected result using OpenAPI Description (yml or json)?
    The actual result is displayed above in the description of the bug.
    The expected result is displayed below.
  • Provide with a sample code (HelloController) or Test that reproduces the problem
    Controller:
@PostMapping
public CompanyDto create(@Valid @RequestBody final CompanyDto companyDto) {
	final Company company = companyMapper.reverse(companyDto);
	final Company createdCompany = companyService.create(company);
	return companyModelAssembler.toModel(createdCompany);
}

CompanyModelAssembler:

@Component
public class CompanyModelAssembler extends RepresentationModelAssemblerSupport<Company, CompanyDto> {

    public CompanyModelAssembler() {
        super(CompanyController.class, CompanyDto.class);
    }

    @Override
    @Nonnull
    public CompanyDto toModel(@Nonnull final Company company) {
        final CompanyDto dto = CompanyDto.builder()
					.id(company.getId())
					.name(company.getName())
					.build();
        final Link selfLink = linkTo(methodOn(CompanyController.class).get(dto.getId())).withSelfRel();
        dto.add(selfLink);
        return dto;
    }
}

DTO:

@AllArgsConstructor
@Data
@Builder
@EqualsAndHashCode(callSuper = false)
@Relation(collectionRelation = "companies", itemRelation = "company")
public class CompanyDto extends RepresentationModel<CompanyDto> {
	@JsonProperty(access = JsonProperty.Access.READ_ONLY)
	private UUID id;
	@NotNull private String name;
}

Expected behavior
I expect Swagger UI to not show the additionalProp*'s in _links but some output that's more in line with the actual output.
Actual RequestBody: POST /company

{
  "name": "string"
}

Actual ReponseBody: POST /company

{
    "id": "5f9d70cd-a425-4502-b78a-29bbb5bb62c3",
    "name": "test",
    "links": [
        {
            "rel": "self",
            "href": "http://localhost:8080/api/company/5f9d70cd-a425-4502-b78a-29bbb5bb62c3"
        }
    ]
}
@bnasslahsen
Copy link
Contributor

bnasslahsen commented Jun 28, 2020

Hi @Flightkick,

For the requestBody content, this is due to the fact that you are using the same object for the request and response. Your DTO extends on RepresentationModel.

We rely on swagger-core project, currently complex (object) payloads are always resolved as a reference to a schema defined in components. If its the same object used, by default, it will use the same reference.

You can use OperationCustomizer, to add a different request body. Or just separate your request and response objects that are used, if you are expecting they have different OpenAPI mappings.

This is tested with the following dependencies:

implementation 'org.springframework.boot:spring-boot-starter-hateoas'
implementation 'org.springdoc:springdoc-openapi-ui:1.4.2'
implementation 'org.springdoc:springdoc-openapi-hateoas:1.4.2'

If you are using spring-boot-starter-hateoas, then use springdoc-openapi-hateoas. (available since v1.4.0)
If you are using spring-boot-starter-data-rest, then use springdoc-openapi-data-rest.

With the next release, you will be able to define different mappings for the same object in the requestBody directly without using OperationCustomizer. An example is available in the tests:

@bnasslahsen bnasslahsen reopened this Jun 28, 2020
bnasslahsen pushed a commit that referenced this issue Jun 28, 2020
@bnasslahsen bnasslahsen added the bug Something isn't working label Jan 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants