Firstly, it's my first time working with OpenAPI, so any comments are welcome.
My question is: OpenAPI generate an interface of my API "PriceControllerApi" that returns a ResponseEntity<PriceDto>
this is the generated DTO by open API. The method that override in my class controller return a ResponseEntity<PriceDto>
but this DTO is my own DTO.
What is the best practice?
- As my service returns my DTO, make a copy of this DTO to the generated DTO and return it on the return
- make a template for the generated API interface that returns my DTO
- Is there any other option that is more correct?
Here is the code
api-docs.json
{
"components": {
"schemas": {
"PriceDto": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"description": "ID del precio",
"format": "int32"
},
"productId": {
"type": "integer",
"description": "ID del producto",
"format": "int64"
},
"brandId": {
"type": "integer",
"description": "ID de la marca",
"format": "int64"
},
"priceList": {
"type": "integer",
"description": "Orden de ofertas",
"format": "int32"
},
"priority": {
"type": "integer",
"description": "Prioridad",
"format": "int32"
},
"startDate": {
"type": "string",
"description": "Fecha inicio de la oferta",
"format": "date-time"
},
"endDate": {
"type": "string",
"description": "Fecha fin de la oferta",
"format": "date-time"
},
"price": {
"description": "Precio unitario",
"format": "double",
"type": "number"
},
"curr": {
"type": "string",
"description": "Tipo de moneda"
}
},
"description": "Objeto que representa el precio"
}
}
},
"info": {
"title": "OpenAPI definition",
"version": "v0"
},
"openapi": "3.0.1",
"paths": {
"/prices": {
"get": {
"tags": [
"price-controller"
],
"summary": "Obtener precio",
"operationId": "getPrice",
"parameters": [
{
"name": "applicationDate",
"in": "query",
"description": "Fecha y hora de la aplicación",
"required": true,
"schema": {
"type": "string",
"format": "date-time",
"example": "2023-05-31T10:30:00"
}
},
{
"name": "productId",
"in": "query",
"description": "Id del producto",
"required": true,
"schema": {
"type": "integer",
"format": "int64"
}
},
{
"name": "brandId",
"in": "query",
"description": "Id de la marca",
"required": true,
"schema": {
"type": "integer",
"format": "int64"
}
}
],
"responses": {
"400": {
"description": "Solicitud inválida"
},
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PriceDto"
}
}
}
},
"404": {
"description": "Valor no encontrado"
}
}
}
}
},
"servers": [
{
"url": "http://localhost:8080",
"description": "Generated server url"}]
}
plugin of pom.xml
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<!-- RELEASE_VERSION -->
<version>5.4.0</version>
<!-- /RELEASE_VERSION -->
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${project.basedir}/api-docs/json/api-docs.json</inputSpec>
<generatorName>spring</generatorName>
<packageName>${project.groupId}.gen</packageName>
<apiPackage>${project.groupId}.gen.api.v1</apiPackage>
<modelPackage>${project.groupId}.gen.dto</modelPackage>
<generateApiTests>false</generateApiTests>
<generateModelTests>false</generateModelTests>
<library>spring-boot</library>
<skipValidateSpec>false</skipValidateSpec>
<configOptions>
<basePackage>com.prueba.test</basePackage>
<reactive>false</reactive>
<delegatePattern>true</delegatePattern>
<interfaceOnly>true</interfaceOnly>
<sourceFolder>src/main/java</sourceFolder>
<!--suppress UnresolvedMavenProperty -->
<additionalModelTypeAnnotations>@lombok.Builder @lombok.NoArgsConstructor @lombok.AllArgsConstructor</additionalModelTypeAnnotations>
<useTags>true</useTags>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
my controller with the first option a mencioned
@Override
public ResponseEntity<com.prueba.gen.dto.PriceDto> getPrice(OffsetDateTime applicationDate, Long productId, Long brandId){
if (applicationDate == null || productId <= 0 || brandId <= 0) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
PriceDto priceDto = this.priceService.getByApplicationDateAndProductIdAndBrandId(applicationDate.toLocalDateTime(), productId, brandId);
if (priceDto.getId() == 0) {
throw new PriceNotFoundException("Price not found for application date " + applicationDate + ", product " + productId + ", brand " + brandId);
}
com.prueba.gen.dto.PriceDto generatedPriceDto = DtoMapper.INSTANCE.mapSourceToDestination(priceDto);
return new ResponseEntity<>(generatedPriceDto,HttpStatus.OK);
}
any contribution or improvement of the code is welcome. Thank you!