OpenAPITools / OpenAPITools/openapi-generator
[BUG][Java][Spring] Incorrect generated code when use application/x-www-form-urlencoded and oneOf
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 26.8k
- Forks
- 7.7k
- PR merge metrics
- PR metrics pending
Description
Bug Report Checklist
- Have you provided a full/minimal spec to reproduce the issue?
- Have you validated the input using an OpenAPI validator (example)?
- Have you tested with the latest master to confirm the issue still exists?
- 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 am designing an API following the oauth2 protocol. In it, the encoding to use is application/x-wwww-form-urlencoded.
Using that encoding algorithm and oneOf feature is not generating the code correctly.
openapi-generator version
6.4.0
OpenAPI declaration file content or url
Minimal sample
openapi: '3.0.0'
info:
title: AuthServer OAuth2
description: This API contains the public paths for the Auth Server
version: 0.0.6
security:
- basicOauthClientAuth: [ ]
paths:
/oauth2/token:
post:
description: Generate OAuth2/OIDC tokens
operationId: token
security:
- basicOauthClientAuth: [ ]
tags:
- OAuth2
requestBody:
description: OAuth2 RO basics grant types
required: true
content:
application/x-www-form-urlencoded:
schema:
oneOf:
- $ref: '#/components/schemas/PasswordGrantTypeForm'
- $ref: '#/components/schemas/AnonymousGrantTypeForm'
discriminator:
propertyName: grant_type
mapping:
password: '#/components/schemas/PasswordGrantTypeForm'
anonymous: '#/components/schemas/AnonymousGrantTypeForm'
responses:
'200':
description: OAuth2/OIDC standard response
content:
application/json:
schema:
$ref: '#/components/schemas/AccessTokenResponse'
components:
securitySchemes:
basicOauthClientAuth:
description: Base64 of the clientId and clientSecret, the format is clientId:clientSecret
type: http
scheme: basic
schemas:
GrantType:
type: object
required:
- grant_type
properties:
grant_type:
type: string
description: Grant type to obtain the token.
example: "password"
PasswordGrantTypeForm:
title: PasswordGrantTypeForm
description: Request body for access token with password grant type for ecommerce customers
allOf:
- $ref: '#/components/schemas/GrantType'
- type: object
properties:
scope:
description: List of scope for the token separated by an space
type: string
example: "session openid"
username:
type: string
description: Account id of the user
example: "4b4d91f2-17b9-46af-b5de-008956ee6f65"
password:
type: string
description: Password of the user
example: "dummyP4ssw0rd"
required:
- username
- password
AnonymousGrantTypeForm:
title: AnonymousGrantTypeForm
description: Request body for access token with anonymous grant type for ecommerce customers
allOf:
- $ref: '#/components/schemas/GrantType'
- type: object
properties:
scope:
description: List of scope for the token separated by an space
type: string
example: "session openid"
anonymous:parameters:account_id:
type: string
description: Account id of the user
example: "4b4d91f2-17b9-46af-b5de-008956ee6f65"
required:
- anonymous:parameters:account_id
AccessTokenResponse:
type: object
required:
- token_type
properties:
token_type:
type: string
id_token:
type: string
description: If the request includes openid scope this field contains a JWT token
Generation Details
java -jar openapi-generator-cli.jar generate -i spec.yml -g spring -o out --global-property skipFormModel=false
Steps to reproduce
- Generate classes
- See OauthApi.java.
Output
- It has been created endpoint with all parameters
- Parameters username and password are created as required --> incorrect
- Discriminator (grandType) should be required --> incorrect
/**
* POST /oauth2/token
* Generate OAuth2/OIDC tokens
*
* @param username Account id of the user (required)
* @param password Password of the user (required)
* @param grantType Grant type to obtain the token. (optional)
* @param scope List of scope for the token separated by an space (optional)
* @param anonymousColonParametersColonAccountId Account id of the user (optional)
* @return OAuth2/OIDC standard response (status code 200)
*/
@Operation(
operationId = "token",
description = "Generate OAuth2/OIDC tokens",
tags = { "OAuth2" },
responses = {
@ApiResponse(responseCode = "200", description = "OAuth2/OIDC standard response", content = {
@Content(mediaType = "application/json", schema = @Schema(implementation = AccessTokenResponse.class))
})
},
security = {
@SecurityRequirement(name = "basicOauthClientAuth")
}
)
@RequestMapping(
method = RequestMethod.POST,
value = "/oauth2/token",
produces = { "application/json" },
consumes = { "application/x-www-form-urlencoded" }
)
default ResponseEntity<AccessTokenResponse> token(
@Parameter(name = "username", description = "Account id of the user", required = true) @Valid @RequestParam(value = "username", required = true) String username,
@Parameter(name = "password", description = "Password of the user", required = true) @Valid @RequestParam(value = "password", required = true) String password,
@Parameter(name = "grant_type", description = "Grant type to obtain the token.") @Valid @RequestParam(value = "grant_type", required = false) String grantType,
@Parameter(name = "scope", description = "List of scope for the token separated by an space") @Valid @RequestParam(value = "scope", required = false) String scope,
@Parameter(name = "anonymous:parameters:account_id", description = "Account id of the user") @Valid @RequestParam(value = "anonymous:parameters:account_id", required = false) String anonymousColonParametersColonAccountId
)
Expected
I was expecting the input parameters to be like when the encoding is application/json.
/**
* POST /oauth2/token
* Generate OAuth2/OIDC tokens
*
* @param tokenRequest OAuth2 RO basics grant types (required)
* @return OAuth2/OIDC standard response (status code 200)
*/
@Operation(
operationId = "token",
description = "Generate OAuth2/OIDC tokens",
tags = { "OAuth2" },
responses = {
@ApiResponse(responseCode = "200", description = "OAuth2/OIDC standard response", content = {
@Content(mediaType = "application/json", schema = @Schema(implementation = AccessTokenResponse.class))
})
},
security = {
@SecurityRequirement(name = "basicOauthClientAuth")
}
)
@RequestMapping(
method = RequestMethod.POST,
value = "/oauth2/token",
produces = { "application/json" },
consumes = { "application/x-www-form-urlencoded" }
)
default ResponseEntity<AccessTokenResponse> token(
@Parameter(name = "TokenRequest", description = "OAuth2 RO basics grant types", required = true) @Valid @RequestBody TokenRequest tokenRequest
)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Run the issue's OpenAPI Generator command with the provided spec and inspect the generated OauthApi.java. Trace how the spring generator handles application/x-www-form-urlencoded request bodies containing oneOf and discriminator schemas. Done means the generated endpoint accepts the form model as one required request body, matching the expected signature rather than exposing individual parameters.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100