[BUG][SPRING-JAVA] Wrong generation result
Bug Report Checklist
- [x] Have you provided a full/minimal spec to reproduce the issue?
- [x] Have you validated the input using an OpenAPI validator (example)?
- [x] Have you tested with the latest master to confirm the issue still exists?
- [x] Have you searched for related issues/PRs?
- [ ] What's the actual output vs expected output?
- [ ] [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description
I identified several common tags for the API in the specification file
openapi-generator version
7.5.0
OpenAPI declaration file content or url
---
openapi: 3.0.0
info:
title: Catalog API
version: 1.0.0
tags:
- name: Material
description: List of All materials
- name: Material Type
description: List of All material types
- name: Material Group
description: List of All material groups
- name: Status
description: List of All statuses
- name: Measurement Unit
description: List of All measurement units
- name: Measuring Point
description: List of All measuring points
- name: Document
description: List of All documents
- name: Document Type
description: List of All document types
paths:
/catalog/v1/api/material-types/{id}:
get:
tags:
- Material Type
description: Get Material Type by id
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
"200":
description: ""
content:
application/json:
schema:
$ref: '#/components/schemas/MaterialTypeEntity'
/catalog/v1/api/material-types:
get:
tags:
- Material Type
description: Get Material Types
parameters:
- name: pageNumber
in: query
description: page number of the list
required: false
schema:
type: integer
- name: pageSize
in: query
description: amount of elements on a page
required: false
schema:
type: integer
- name: sort
in: query
description: sort parameter
required: false
schema:
type: string
responses:
"200":
description: ""
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/Page'
- type: object
properties:
content:
type: array
items:
$ref: '#/components/schemas/MaterialTypeEntity'
/catalog/v1/api/material-groups/{id}:
get:
tags:
- Material Group
description: Get Material Group by id
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
"200":
description: ""
content:
application/json:
schema:
$ref: '#/components/schemas/MaterialGroupEntity'
/catalog/v1/api/material-groups:
get:
tags:
- Material Group
description: Get Material Groups
parameters:
- name: pageNumber
in: query
description: page number of the list
required: false
schema:
type: integer
- name: pageSize
in: query
description: amount of elements on a page
required: false
schema:
type: integer
- name: sort
in: query
description: sort parameter
required: false
schema:
type: string
responses:
"200":
description: ""
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/Page'
- type: object
properties:
content:
type: array
items:
$ref: '#/components/schemas/MaterialGroupEntity'
/catalog/v1/api/materials/{id}:
get:
tags:
- Material
description: Get Material by id
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
"200":
description: ""
content:
application/json:
schema:
$ref: '#/components/schemas/MaterialEntity'
/catalog/v1/api/materials:
get:
x-spring-paginated: true
tags:
- Material
description: Get list of Materials
parameters:
- name: id
in: query
description: id of the required material
required: false
schema:
type: string
- name: statusId
in: query
description: exception status of the required material
required: false
schema:
type: string
- name: pageNumber
in: query
description: page number of the list
required: false
schema:
type: integer
- name: pageSize
in: query
description: amount of elements on a page
required: false
schema:
type: integer
- name: sort
in: query
description: sort parameter
required: false
schema:
type: string
responses:
"200":
description: ""
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/Page'
- type: object
properties:
content:
type: array
items:
$ref: '#/components/schemas/MaterialEntity'
post:
tags:
- Material
description: Create temporal material
requestBody:
description: A JSON object of a temporal material
content:
application/json:
schema:
$ref: '#/components/schemas/TemporalMaterialRequest'
responses:
"200":
description: ""
content:
application/json:
schema:
$ref: '#/components/schemas/TemporalMaterialResponse'
/catalog/v1/api/statuses/{id}:
get:
tags:
- Status
description: Get Status by id
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
"200":
description: ""
content:
application/json:
schema:
$ref: '#/components/schemas/StatusEntity'
/catalog/v1/api/statuses:
get:
x-spring-paginated: true
tags:
- Status
description: Get list of All statuses
parameters:
- name: pageNumber
in: query
description: page number of the list
required: false
schema:
type: integer
- name: pageSize
in: query
description: amount of elements on a page
required: false
schema:
type: integer
- name: category
in: query
description: category of the status
required: true
schema:
type: string
- name: sort
in: query
description: sort parameter
required: false
schema:
type: string
responses:
"200":
description: ""
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/Page'
- type: object
properties:
content:
type: array
items:
$ref: '#/components/schemas/StatusEntity'
/catalog/v1/api/measurement-units/{id}:
get:
tags:
- Measurement Unit
description: Get Measurement Unit by id
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
"200":
description: ""
content:
application/json:
schema:
$ref: '#/components/schemas/MeasurementUnitEntity'
/catalog/v1/api/measurement-units:
get:
x-spring-paginated: true
tags:
- Measurement Unit
description: Get list of All Measurement Units
parameters:
- name: pageNumber
in: query
description: page number of the list
required: false
schema:
type: integer
- name: pageSize
in: query
description: amount of elements on a page
required: false
schema:
type: integer
- name: sort
in: query
description: sort parameter
required: false
schema:
type: string
responses:
"200":
description: ""
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/Page'
- type: object
properties:
content:
type: array
items:
$ref: '#/components/schemas/MeasurementUnitEntity'
/catalog/v1/api/measuting-points/{id}:
get:
tags:
- Measuring Point
description: Get Measuring Point by id
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
"200":
description: ""
content:
application/json:
schema:
$ref: '#/components/schemas/MeasuringPointEntity'
/catalog/v1/api/measuting-points:
get:
x-spring-paginated: true
tags:
- Measuring Point
description: Get list of All Measuring Points
parameters:
- name: pageNumber
in: query
description: page number of the list
required: false
schema:
type: integer
- name: pageSize
in: query
description: amount of elements on a page
required: false
schema:
type: integer
- name: sort
in: query
description: sort parameter
required: false
schema:
type: string
responses:
"200":
description: ""
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/Page'
- type: object
properties:
content:
type: array
items:
$ref: '#/components/schemas/MeasuringPointEntity'
/catalog/v1/api/document-types/{id}:
get:
tags:
- Document Type
description: Get Document Type by id
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
"200":
description: ""
content:
application/json:
schema:
$ref: '#/components/schemas/DocumentTypeEntity'
/catalog/v1/api/document-types:
get:
x-spring-paginated: true
tags:
- Document Type
description: Get list of All Document Types
parameters:
- name: pageNumber
in: query
description: page number of the list
required: false
schema:
type: integer
- name: pageSize
in: query
description: amount of elements on a page
required: false
schema:
type: integer
- name: sort
in: query
description: sort parameter
required: false
schema:
type: string
responses:
"200":
description: ""
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/Page'
- type: object
properties:
content:
type: array
items:
$ref: '#/components/schemas/DocumentTypeEntity'
/catalog/v1/api/documents/{id}:
get:
tags:
- Document
description: Get Document by id
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
"200":
description: ""
content:
application/json:
schema:
$ref: '#/components/schemas/DocumentEntity'
/catalog/v1/api/documents:
get:
tags:
- Document
description: Get list of All Documents
parameters:
- name: search
in: query
required: false
schema:
type: string
- name: techPlace
in: query
required: false
schema:
type: string
- name: documentKind
in: query
required: false
schema:
type: string
- name: documentTypeId
in: query
required: false
schema:
type: string
- name: pageNumber
in: query
description: page number of the list
required: false
schema:
type: integer
- name: pageSize
in: query
description: amount of elements on a page
required: false
schema:
type: integer
- name: sort
in: query
description: sort parameter
required: false
schema:
type: string
responses:
"200":
description: ""
content:
application/json:
schema:
allOf:
- $ref: '#/components/schemas/Page'
- type: object
properties:
content:
type: array
items:
$ref: '#/components/schemas/DocumentEntity'
post:
tags:
- Document
description: Create document
requestBody:
description: An object of a document
content:
multipart/form-data:
schema:
type: object
required: [ file,documentKind,documentTypeId, tm/eoCode ]
properties:
file:
type: array
items:
type: string
format: binary
documentKind:
type: string
documentTypeId:
type: string
tm/eoCode:
type: string
responses:
"200":
description: ""
content:
application/json:
schema:
$ref: '#/components/schemas/DocumentEntity'
components:
schemas:
Page:
type: object
properties:
content:
type: array
items:
type: object
pageable:
$ref: '#/components/schemas/Pageable'
last:
type: boolean
totalElements:
type: integer
totalPages:
type: integer
first:
type: boolean
numberOfElements:
type: integer
empty:
type: boolean
Pageable:
type: object
properties:
pageSize:
type: integer
pageNumber:
type: integer
sort:
$ref: '#/components/schemas/Sort'
Sort:
type: object
properties:
sorted:
type: boolean
unsorted:
type: boolean
MaterialTypeEntity:
required:
- id
- name
properties:
id:
type: string
name:
type: string
type: object
MaterialGroupEntity:
required:
- id
- name
properties:
id:
type: string
name:
type: string
type: object
MaterialEntity:
required:
- id
- name
- price
- measurementUnit
- amount
- materialTypeId
- materialType
- materialGroupId
- materialGroup
properties:
id:
type: string
name:
type: string
price:
type: number
measurementUnit:
$ref: '#/components/schemas/MeasurementUnitEntity'
amount:
type: integer
materialTypeId:
type: string
materialType:
$ref: '#/components/schemas/MaterialTypeEntity'
materialGroupId:
type: string
materialGroup:
$ref: '#/components/schemas/MaterialGroupEntity'
type: object
TemporalMaterialRequest:
required:
- name
- price
- measurementUnitId
- amount
properties:
name:
type: string
price:
type: number
measurementUnitId:
type: string
amount:
type: integer
type: object
TemporalMaterialResponse:
required:
- id
- name
- price
- measurementUnit
- amount
properties:
id:
type: string
name:
type: string
price:
type: number
measurementUnit:
$ref: '#/components/schemas/MeasurementUnitEntity'
amount:
type: integer
type: object
StatusEntity:
required:
- id
- name
properties:
id:
type: string
name:
type: string
type: object
MeasurementUnitEntity:
required:
- id
- name
properties:
id:
type: string
name:
type: string
type: object
MeasuringPointEntity:
required:
- id
- measuringPointKind
- name
- position
- description
- codeGroup
- nodeId
- type
properties:
id:
type: string
measuringPointKind:
type: string
name:
type: string
position:
type: string
description:
type: string
codeGroup:
type: string
nodeId:
type: string
type:
type: string
type: object
DocumentTypeEntity:
required:
- id
- name
properties:
id:
type: string
name:
type: string
type: object
DocumentEntity:
required:
- id
- name
- status
- date
- documentKind
- documentType
- tm/eoCode
- link
properties:
id:
type: string
name:
type: string
status:
$ref: '#/components/schemas/StatusEntity'
date:
type: string
documentKind:
type: string
documentType:
$ref: '#/components/schemas/DocumentTypeEntity'
tm/eoCode:
type: string
link:
type: string
type: object
Generation Details
I use configuration in the mvn pom.xml
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>7.5.0</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<skipValidateSpec>false</skipValidateSpec>
<inputSpec>./src/main/resources/catalogAPI.yaml</inputSpec>
<generatorName>spring</generatorName>
<importMappings>
<importMapping>Pageable=org.springframework.data.domain.Pageable</importMapping>
<importMapping>Page=org.springframework.data.domain.PageImpl</importMapping>
<importMapping>Sort=org.springframework.data.domain.Sort</importMapping>
</importMappings>
<configOptions>
<useSpringBoot3>true</useSpringBoot3>
<openApiNullable>false</openApiNullable>
<interfaceOnly>true</interfaceOnly>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
And I see result of
@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", comments = "Generator version: 7.5.0")
@Validated
@Tag(name = "Document Type", description = "List of All document types")
public interface CatalogApi {
And it makes for every request additional tag of Document Type when only several requests belong to it
Steps to reproduce
execution of mvn clean package
Related issues/PRs
Didn't found any
Suggest a fix
I didn't find workaround for that
All your endpoints starts with /catalog. That produces the CatalogApi.
What you probably want is to use some configOptions described here : https://openapi-generator.tech/docs/generators/spring/
for example <useTags>true</useTags> will produce several interfaces: DocumentApi, MaterialTypeApi, MaterialGroupApi...
The other solution is to remove /catalog/v1/api from the endpoints and use only the relevant end (for example /material-types/{id}) -> it will produce a MaterialTypesApi interface
then you have 2 options:
add the following to your contract.
servers:
- url: /catalog/v1/api
and correctly configure the configOptions requestMappingMode.
either add @RequestMapping("/catalog/v1/api") to your controllers
@jpfinne I mean, that it adds @Tag annotation of Document type on a controller class and either additional tags on endpoints. So it makes additional tag for every endpoint so that I see that all endpoints belongs to Document Type tag which is wrong behaviour. Thank you for your impact!