OpenAPITools / OpenAPITools/openapi-generator

[BUG] Kotlin server does not escape special character ('$') in jackson annotation

Open
#20,960 9 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Issue: Bug
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

The given schema component with a special character in a property name.

(Example: "Group" schema from SCIM)

Using the kotlin server generator with jackson serializer generates invalid code

data class BaseGroupMembersInner (

    /* The `id` of the member.  Each value MUST be the `id` of the corresponding `User` resource, which is unique across the service provider's entire set of resources.  */

    @JsonProperty("value")
    val `value`: java.util.UUID,

    /* The URI of the corresponding `User` resource.  Nullable for requests but required for responses.  */

    @JsonProperty("$ref")
    val dollarRef: kotlin.String? = null

)

It should escape the special character ($)

@JsonProperty("\$ref")

openapi-generator version

7.11.0

OpenAPI declaration file content or url
openapi: 3.1.0

info:
  version: 5.0.5
  title: Internal Users SCIM
  description: ...
tags:
  - name: Groups
    description: ...

paths:
  /v3/internal/scim/Groups/{id}:
    get:
      summary: 'Get group by id'
      description: ...
      externalDocs:
        url: 'https://datatracker.ietf.org/doc/html/rfc7644#section-3.2'
        description: 'RFC 7644, Section 3.2'
      operationId: getGroup
      tags:
        - Groups
      parameters:
        - $ref: '#/components/parameters/GroupIdInPath'
      responses:
        '200':
          description: Successful response
          content:
            application/scim+json:
              schema:
                $ref: '#/components/schemas/Group'
            application/json:
              schema:
                $ref: '#/components/schemas/Group'

components:
  parameters:
    GroupIdInPath:
      name: id
      in: path
      description: |
        The unique identifier of a group
      required: true
      schema:
        type: string
        format: uuid
  schemas:
    Meta:
      type: object
      description: ...
      externalDocs:
        url: 'https://datatracker.ietf.org/doc/html/rfc7643#section-3.1'
        description: 'RFC 7643, Section 3.1'
      properties:
        resourceType:
          type: string
          description: ...
          examples:
            - 'ResourceType'
        created:
          type: string
          format: date-time
          description: ...
          examples:
            - '2024-07-21T17:32:28Z'
        lastModified:
          type: string
          format: date-time
          description: ...
        location:
          type: string
          description: ...
        version:
          type: string
          description: ...
    BaseGroup:
      type: object
      description: ...
      externalDocs:
        url: 'https://datatracker.ietf.org/doc/html/rfc7643#section-4'
        description: 'RFC 7643, Section 4'
      required:
        - members
      properties:
        members:
          type: array
          description: ...
          items:
            type: object
            required:
              - value
            properties:
              value:
                type: string
                format: uuid
                description: ...
              $ref:
                type:
                  - "string"
                  - "null"
                description: ...
          default: [ ] # default is for `PUT` request
    Group:
      type: object
      description: ...
      externalDocs:
        url: 'https://datatracker.ietf.org/doc/html/rfc7643#section-4'
        description: 'RFC 7643, Section 4'
      required:
        - schemas
        - id
        - displayName
        - members
      allOf:
        - type: object
          properties:
            schemas:
              type: array
              description: ...
              items:
                type: string
            id:
              type: string
              format: uuid
              readOnly: true
              description: ...
            displayName:
              type: string
              readOnly: true
              description: ...
        - $ref: '#/components/schemas/BaseGroup'
Generation Details

Gradle configuration

openApiGenerate {
    generatorName = "kotlin-server"
    inputSpec = "${rootProject.projectDir}/rest-application/src/main/resources/test-petstore-api.yml"
    library.convention("jaxrs-spec")
    outputDir.convention("${project.layout.buildDirectory.get()}/generated-rest/server/scim")
    apiPackage.convention("com.toasttab.service.scim.api")
    modelPackage.convention("com.toasttab.service.scim.models")
    packageName.convention("com.toasttab.service.scim")
    additionalProperties.convention(
        mapOf(
            "collectionType" to "list",
            "enumPropertyNaming" to "UPPERCASE",
            "dateLibrary" to "java8",
            "interfaceOnly" to "true",
            "returnResponse" to "true"
        )
    )
}
Steps to reproduce
  1. Define a schema wit a property name of $ref
  2. Configure opernapi generator with generatorName = "kotlin-server" AND library.convention("jaxrs-spec")
  3. Attempt to generate server side code
Related issues/PRs
Suggest a fix

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the kotlin-server generator entry point using the jaxrs-spec library and reproduce the issue with the provided schema and Gradle configuration. Compare the generated BaseGroupMembersInner output with the expected escaped @JsonProperty("$ref") form. Done means the generated Kotlin source is valid and preserves the $ref property name.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, kotlin, openapi
Domain
api, tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.