From 0a85fbbdd69cd31a4e0d380a48715458dddcbfa4 Mon Sep 17 00:00:00 2001 From: vivek kumar <51886550+vivekkumarq@users.noreply.github.com> Date: Sun, 30 Aug 2026 12:35:46 +0530 Subject: [PATCH] fix(kotlin-server): emit KDoc for operation summary and description in jaxrs-spec interfaces The kotlin-server jaxrs-spec apiInterface template emitted only the JAX-RS annotations, so an interfaceOnly API interface carried no documentation at all for its operations. The equivalent Java template (JavaJaxRS/spec) has always emitted a Javadoc block, and the models generated by this same library already carry KDoc, so the API interfaces were the odd ones out. Emit a KDoc block built from the operation summary and notes, with @param for documented parameters and @return listing the responses. The @return formatting follows the kotlin-server javalin6 templates so the output is consistent across the generator. The block is omitted entirely when an operation has neither a summary nor notes, rather than emitting an empty comment. The body shared by the summary and notes branches lives in an operationDoc partial so the two do not drift. File form parameters are documented under the name formParams.mustache actually generates for them, which appends an InputStream suffix. Fixes #24794 --- .../jaxrs-spec/apiInterface.mustache | 16 ++++++ .../jaxrs-spec/operationDoc.mustache | 13 +++++ .../org/openapitools/server/apis/StuffApi.kt | 14 +++++ .../org/openapitools/server/apis/PetApi.kt | 57 +++++++++++++++++++ .../org/openapitools/server/apis/StoreApi.kt | 29 ++++++++++ .../org/openapitools/server/apis/UserApi.kt | 52 +++++++++++++++++ 6 files changed, 181 insertions(+) create mode 100644 modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/operationDoc.mustache diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/apiInterface.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/apiInterface.mustache index c1eccb534dba..57f95876f858 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/apiInterface.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/apiInterface.mustache @@ -1,3 +1,19 @@ + {{#summary}} + /** + * {{{summary}}} + {{#notes}} + * + * {{{notes}}} + {{/notes}} +{{>operationDoc}} + {{/summary}} + {{^summary}} + {{#notes}} + /** + * {{{notes}}} +{{>operationDoc}} + {{/notes}} + {{/summary}} @{{httpMethod}}{{#subresourceOperation}} @Path("{{{path}}}"){{/subresourceOperation}}{{#hasConsumes}} @Consumes({{#consumes}}"{{{mediaType}}}"{{^-last}}, {{/-last}}{{/consumes}}){{/hasConsumes}}{{#hasProduces}} diff --git a/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/operationDoc.mustache b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/operationDoc.mustache new file mode 100644 index 000000000000..c674467fb420 --- /dev/null +++ b/modules/openapi-generator/src/main/resources/kotlin-server/libraries/jaxrs-spec/operationDoc.mustache @@ -0,0 +1,13 @@ +{{#allParams}} +{{#description}} + * @param {{paramName}}{{#isFormParam}}{{#isFile}}InputStream{{/isFile}}{{/isFormParam}} {{{description}}} +{{/description}} +{{/allParams}} +{{#responses.0}} + * @return {{#responses}}{{{message}}} (status code {{code}}){{^-last}} + * or {{/-last}}{{/responses}} +{{/responses.0}} +{{#isDeprecated}} + * @deprecated +{{/isDeprecated}} + */ diff --git a/samples/server/others/kotlin-server/jaxrs-spec-array-response/src/main/kotlin/org/openapitools/server/apis/StuffApi.kt b/samples/server/others/kotlin-server/jaxrs-spec-array-response/src/main/kotlin/org/openapitools/server/apis/StuffApi.kt index 02285f677b98..a69f188bb7f1 100644 --- a/samples/server/others/kotlin-server/jaxrs-spec-array-response/src/main/kotlin/org/openapitools/server/apis/StuffApi.kt +++ b/samples/server/others/kotlin-server/jaxrs-spec-array-response/src/main/kotlin/org/openapitools/server/apis/StuffApi.kt @@ -14,11 +14,25 @@ import java.io.InputStream @jakarta.annotation.Generated(value = arrayOf("org.openapitools.codegen.languages.KotlinServerCodegen"), comments = "Generator version: 7.26.0-SNAPSHOT") interface StuffApi { + /** + * Finds stuff + * + * Finds stuff + * @return successful operation (status code 200) + * or Invalid status value (status code 400) + */ @GET @Path("/stuff") @Produces("application/json") fun findStuff(): kotlin.collections.List + /** + * Finds unique stuff + * + * Finds unique stuff + * @return successful operation (status code 200) + * or Invalid status value (status code 400) + */ @GET @Path("/uniquestuff") @Produces("application/json") diff --git a/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/PetApi.kt b/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/PetApi.kt index 528390ef798f..3e96f79afb43 100644 --- a/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/PetApi.kt +++ b/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/PetApi.kt @@ -15,38 +15,95 @@ import java.io.InputStream @javax.annotation.Generated(value = arrayOf("org.openapitools.codegen.languages.KotlinServerCodegen"), comments = "Generator version: 7.26.0-SNAPSHOT") interface PetApi { + /** + * Add a new pet to the store + * @param body Pet object that needs to be added to the store + * @return Invalid input (status code 405) + */ @POST @Consumes("application/json", "application/xml") fun addPet( body: Pet): io.smallrye.mutiny.Uni + /** + * Deletes a pet + * @param petId Pet id to delete + * @return Invalid pet value (status code 400) + */ @DELETE @Path("/{petId}") fun deletePet(@PathParam("petId") petId: kotlin.Long,@HeaderParam("api_key") apiKey: kotlin.String?): io.smallrye.mutiny.Uni + /** + * Finds Pets by status + * + * Multiple status values can be provided with comma separated strings + * @param status Status values that need to be considered for filter + * @return successful operation (status code 200) + * or Invalid status value (status code 400) + */ @GET @Path("/findByStatus") @Produces("application/xml", "application/json") fun findPetsByStatus(@QueryParam("status") status: kotlin.collections.List): io.smallrye.mutiny.Uni + /** + * Finds Pets by tags + * + * Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. + * @param tags Tags to filter by + * @return successful operation (status code 200) + * or Invalid tag value (status code 400) + * @deprecated + */ @GET @Path("/findByTags") @Produces("application/xml", "application/json") fun findPetsByTags(@QueryParam("tags") tags: kotlin.collections.List): io.smallrye.mutiny.Uni + /** + * Find pet by ID + * + * Returns a single pet + * @param petId ID of pet to return + * @return successful operation (status code 200) + * or Invalid ID supplied (status code 400) + * or Pet not found (status code 404) + */ @GET @Path("/{petId}") @Produces("application/xml", "application/json") fun getPetById(@PathParam("petId") petId: kotlin.Long): io.smallrye.mutiny.Uni + /** + * Update an existing pet + * @param body Pet object that needs to be added to the store + * @return Invalid ID supplied (status code 400) + * or Pet not found (status code 404) + * or Validation exception (status code 405) + */ @PUT @Consumes("application/json", "application/xml") fun updatePet( body: Pet): io.smallrye.mutiny.Uni + /** + * Updates a pet in the store with form data + * @param petId ID of pet that needs to be updated + * @param name Updated name of the pet + * @param status Updated status of the pet + * @return Invalid input (status code 405) + */ @POST @Path("/{petId}") @Consumes("application/x-www-form-urlencoded") fun updatePetWithForm(@PathParam("petId") petId: kotlin.Long,@FormParam(value = "name") name: kotlin.String?,@FormParam(value = "status") status: kotlin.String?): io.smallrye.mutiny.Uni + /** + * uploads an image + * @param petId ID of pet to update + * @param additionalMetadata Additional data to pass to server + * @param fileInputStream file to upload + * @return successful operation (status code 200) + */ @POST @Path("/{petId}/uploadImage") @Consumes("multipart/form-data") diff --git a/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt b/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt index 830776221b38..917e2d20f44c 100644 --- a/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt +++ b/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/StoreApi.kt @@ -14,20 +14,49 @@ import java.io.InputStream @javax.annotation.Generated(value = arrayOf("org.openapitools.codegen.languages.KotlinServerCodegen"), comments = "Generator version: 7.26.0-SNAPSHOT") interface StoreApi { + /** + * Delete purchase order by ID + * + * For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors + * @param orderId ID of the order that needs to be deleted + * @return Invalid ID supplied (status code 400) + * or Order not found (status code 404) + */ @DELETE @Path("/order/{orderId}") fun deleteOrder(@PathParam("orderId") orderId: kotlin.String): io.smallrye.mutiny.Uni + /** + * Returns pet inventories by status + * + * Returns a map of status codes to quantities + * @return successful operation (status code 200) + */ @GET @Path("/inventory") @Produces("application/json") fun getInventory(): io.smallrye.mutiny.Uni + /** + * Find purchase order by ID + * + * For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions + * @param orderId ID of pet that needs to be fetched + * @return successful operation (status code 200) + * or Invalid ID supplied (status code 400) + * or Order not found (status code 404) + */ @GET @Path("/order/{orderId}") @Produces("application/xml", "application/json") fun getOrderById(@PathParam("orderId") orderId: kotlin.Long): io.smallrye.mutiny.Uni + /** + * Place an order for a pet + * @param body order placed for purchasing the pet + * @return successful operation (status code 200) + * or Invalid Order (status code 400) + */ @POST @Path("/order") @Produces("application/xml", "application/json") diff --git a/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/UserApi.kt b/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/UserApi.kt index 99df5258a6db..a706f34ae242 100644 --- a/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/UserApi.kt +++ b/samples/server/petstore/kotlin-server/jaxrs-spec-mutiny/src/main/kotlin/org/openapitools/server/apis/UserApi.kt @@ -14,35 +14,87 @@ import java.io.InputStream @javax.annotation.Generated(value = arrayOf("org.openapitools.codegen.languages.KotlinServerCodegen"), comments = "Generator version: 7.26.0-SNAPSHOT") interface UserApi { + /** + * Create user + * + * This can only be done by the logged in user. + * @param body Created user object + * @return successful operation (status code 0) + */ @POST fun createUser( body: User): io.smallrye.mutiny.Uni + /** + * Creates list of users with given input array + * @param body List of user object + * @return successful operation (status code 0) + */ @POST @Path("/createWithArray") fun createUsersWithArrayInput( body: kotlin.collections.List): io.smallrye.mutiny.Uni + /** + * Creates list of users with given input array + * @param body List of user object + * @return successful operation (status code 0) + */ @POST @Path("/createWithList") fun createUsersWithListInput( body: kotlin.collections.List): io.smallrye.mutiny.Uni + /** + * Delete user + * + * This can only be done by the logged in user. + * @param username The name that needs to be deleted + * @return Invalid username supplied (status code 400) + * or User not found (status code 404) + */ @DELETE @Path("/{username}") fun deleteUser(@PathParam("username") username: kotlin.String): io.smallrye.mutiny.Uni + /** + * Get user by user name + * @param username The name that needs to be fetched. Use user1 for testing. + * @return successful operation (status code 200) + * or Invalid username supplied (status code 400) + * or User not found (status code 404) + */ @GET @Path("/{username}") @Produces("application/xml", "application/json") fun getUserByName(@PathParam("username") username: kotlin.String): io.smallrye.mutiny.Uni + /** + * Logs user into the system + * @param username The user name for login + * @param password The password for login in clear text + * @return successful operation (status code 200) + * or Invalid username/password supplied (status code 400) + */ @GET @Path("/login") @Produces("application/xml", "application/json") fun loginUser(@QueryParam("username") username: kotlin.String,@QueryParam("password") password: kotlin.String): io.smallrye.mutiny.Uni + /** + * Logs out current logged in user session + * @return successful operation (status code 0) + */ @GET @Path("/logout") fun logoutUser(): io.smallrye.mutiny.Uni + /** + * Updated user + * + * This can only be done by the logged in user. + * @param username name that need to be deleted + * @param body Updated user object + * @return Invalid user supplied (status code 400) + * or User not found (status code 404) + */ @PUT @Path("/{username}") fun updateUser(@PathParam("username") username: kotlin.String, body: User): io.smallrye.mutiny.Uni