Improving Misk Kotlin Server Generator (#20973)

* first pass

* fixing types

* fixing action

* updating samples

* updating files

* adding guido

* fixing misk

* removing old files

* cleaning generated files

* cleaning generated files

* adding back in license
This commit is contained in:
Andrew Wilson 2025-04-04 08:37:49 +01:00 committed by GitHub
parent 04169ec29b
commit 9bac31859c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
16 changed files with 66 additions and 59 deletions

View File

@ -1139,7 +1139,7 @@ Here is a list of template creators:
* Kotlin (Spring Boot): @dr4ke616 * Kotlin (Spring Boot): @dr4ke616
* Kotlin (Vertx): @Wooyme * Kotlin (Vertx): @Wooyme
* Kotlin (JAX-RS): @anttileppa * Kotlin (JAX-RS): @anttileppa
* Kotlin Misk: @andrewwilsonnew * Kotlin Misk: @andrewwilsonnew @guiarn
* Kotlin WireMock: @stefankoppier * Kotlin WireMock: @stefankoppier
* NodeJS Express: @YishTish * NodeJS Express: @YishTish
* PHP Flight: @daniel-sc * PHP Flight: @daniel-sc

View File

@ -57,8 +57,7 @@ public class KotlinMiskServerCodegen extends AbstractKotlinCodegen implements Be
protected String rootPackage = "org.openapitools.server.api"; protected String rootPackage = "org.openapitools.server.api";
protected String apiVersion = "1.0.0-SNAPSHOT"; protected String apiVersion = "1.0.0-SNAPSHOT";
@Setter @Setter protected String moduleClassName = "OpenApiModule";
protected String moduleClassName = "OpenApiModule";
@Override @Override
public CodegenType getTag() { public CodegenType getTag() {
@ -122,7 +121,7 @@ public class KotlinMiskServerCodegen extends AbstractKotlinCodegen implements Be
supportingFiles.clear(); supportingFiles.clear();
apiTemplateFiles.clear(); apiTemplateFiles.clear();
apiTemplateFiles.put("apiController.mustache", "Controller.kt"); apiTemplateFiles.put("apiAction.mustache", "Action.kt");
apiTemplateFiles.put("apiImpl.mustache", "Impl.kt"); apiTemplateFiles.put("apiImpl.mustache", "Impl.kt");
apiTemplateFiles.put("apiInterface.mustache", ".kt"); apiTemplateFiles.put("apiInterface.mustache", ".kt");
modelTemplateFiles.put("model.mustache", ".kt"); modelTemplateFiles.put("model.mustache", ".kt");
@ -199,30 +198,38 @@ public class KotlinMiskServerCodegen extends AbstractKotlinCodegen implements Be
} }
private String mapMediaType(String mediaType) { private String mapMediaType(String mediaType) {
return MEDIA_MAPPING.getOrDefault(mediaType, "MediaTypes.APPLICATION_OCTETSTREAM /* unknown -> " + mediaType + " */ "); return MEDIA_MAPPING.getOrDefault(mediaType, "MediaTypes.APPLICATION_OCTETSTREAM /* @todo(unknown) -> " + mediaType + " */ ");
} }
private final static Map<String, String> MEDIA_MAPPING = getMappings(); private final static Map<String, String> MEDIA_MAPPING = getMappings();
private static Map<String, String> getMappings() { private static Map<String, String> getMappings() {
// add new values in order
Map<String, String> result = new HashMap<>(); Map<String, String> result = new HashMap<>();
result.put("application/json", "MediaTypes.APPLICATION_JSON");
result.put("application/xml", "MediaTypes.APPLICATION_XML");
result.put("application/javascript", "MediaTypes.APPLICATION_JAVASCRIPT");
result.put("*/*", "MediaTypes.ALL"); result.put("*/*", "MediaTypes.ALL");
result.put("application/x-www-form-urlencoded", "MediaTypes.APPLICATION_FORM_URLENCODED");
result.put("application/grpc", "MediaTypes.APPLICATION_GRPC");
result.put("application/javascript", "MediaTypes.APPLICATION_JAVASCRIPT");
result.put("application/json", "MediaTypes.APPLICATION_JSON");
result.put("application/octetstream", "MediaTypes.APPLICATION_OCTETSTREAM"); result.put("application/octetstream", "MediaTypes.APPLICATION_OCTETSTREAM");
result.put("application/pdf", "MediaTypes.APPLICATION_OCTETSTREAM"); result.put("application/pdf", "MediaTypes.APPLICATION_OCTETSTREAM");
result.put("application/x-protobuf", "MediaTypes.APPLICATION_PROTOBUF"); result.put("application/x-protobuf", "MediaTypes.APPLICATION_PROTOBUF");
result.put("application/grpc", "MediaTypes.APPLICATION_GRPC"); result.put("application/x-www-form-urlencoded", "MediaTypes.APPLICATION_FORM_URLENCODED");
result.put("application/xml", "MediaTypes.APPLICATION_XML");
result.put("application/zip", "MediaTypes.APPLICATION_ZIP");
result.put("image/gif", "MediaTypes.IMAGE_GIF");
result.put("image/jpeg", "MediaTypes.IMAGE_JPEG");
result.put("image/png", "MediaTypes.IMAGE_PNG");
result.put("image/svg+xml", "MediaTypes.IMAGE_SVG");
result.put("image/x-icon", "MediaTypes.IMAGE_ICO");
result.put("multipart/form-data", "MediaTypes.FORM_DATA");
result.put("text/css", "MediaTypes.TEXT_CSS"); result.put("text/css", "MediaTypes.TEXT_CSS");
result.put("text/html", "MediaTypes.TEXT_HTML"); result.put("text/html", "MediaTypes.TEXT_HTML");
result.put("text/plain", "MediaTypes.TEXT_PLAIN_UTF8"); result.put("text/plain", "MediaTypes.TEXT_PLAIN_UTF8");
result.put("image/png", "MediaTypes.IMAGE_PNG");
result.put("image/svg+xml", "MediaTypes.IMAGE_SVG");
result.put("image/jpeg", "MediaTypes.IMAGE_JPEG");
result.put("image/gif", "MediaTypes.IMAGE_GIF");
result.put("image/x-icon", "MediaTypes.IMAGE_ICO");
return result; return result;
} }
} }

View File

@ -34,10 +34,10 @@ import misk.web.mediatype.MediaTypes
{{#operations}} {{#operations}}
/** /**
* Generated file, please change {{classname}}Controller. * Generated file, please change {{classname}}Impl.
*/ */
@Singleton @Singleton
class {{classname}}Controller @Inject constructor( class {{classname}}Action @Inject constructor(
private val {{#lambda.camelcase}}{{classname}}{{/lambda.camelcase}}: {{classname}} private val {{#lambda.camelcase}}{{classname}}{{/lambda.camelcase}}: {{classname}}
) : WebAction, {{classname}} { ) : WebAction, {{classname}} {
{{#operation}} {{#operation}}

View File

@ -21,7 +21,7 @@ internal class {{classname}}Test {
{{#operations}} {{#operations}}
{{#operation}} {{#operation}}
/** /**
* To test {{classname}}Controller.{{operationId}} * To test {{classname}}Action.{{operationId}}
*/ */
@Test @Test
fun `should handle {{operationId}}`() { fun `should handle {{operationId}}`() {

View File

@ -9,7 +9,7 @@ version = "{{artifactVersion}}"
dependencies { dependencies {
implementation("jakarta.validation:jakarta.validation-api:3.1.1") implementation("jakarta.validation:jakarta.validation-api:3.1.1")
implementation("com.squareup.misk:misk:2025.03.17.160337-2c6953c") implementation("com.squareup.misk:misk:2025.04.02.195630-a61d550")
//implementation("com.squareup.wire:wire-runtime:5.2.1") //implementation("com.squareup.wire:wire-runtime:5.2.1")
testImplementation("com.squareup.misk:misk-testing:2025.02.11.123913-8a41324") testImplementation("com.squareup.misk:misk-testing:2025.02.11.123913-8a41324")

View File

@ -6,7 +6,7 @@ import {{javaxPackage}}.inject.Singleton
{{#apiInfo}} {{#apiInfo}}
{{#apis}} {{#apis}}
{{#operations}} {{#operations}}
import {{apiPackage}}.{{classname}}Controller import {{apiPackage}}.{{classname}}Action
{{/operations}} {{/operations}}
{{/apis}} {{/apis}}
{{/apiInfo}} {{/apiInfo}}
@ -17,7 +17,7 @@ class {{moduleClassName}} : KAbstractModule() {
{{#apiInfo}} {{#apiInfo}}
{{#apis}} {{#apis}}
{{#operations}} {{#operations}}
install(WebActionModule.create<{{classname}}Controller>()) install(WebActionModule.create<{{classname}}Action>())
{{/operations}} {{/operations}}
{{/apis}} {{/apis}}
{{/apiInfo}} {{/apiInfo}}

View File

@ -11,14 +11,14 @@ docs/User.md
docs/UserApi.md docs/UserApi.md
settings.gradle.kts settings.gradle.kts
src/main/kotlin/org/openapitools/server/api/api/PetApi.kt src/main/kotlin/org/openapitools/server/api/api/PetApi.kt
src/main/kotlin/org/openapitools/server/api/api/PetApiController.kt src/main/kotlin/org/openapitools/server/api/api/PetApiAction.kt
src/main/kotlin/org/openapitools/server/api/api/PetApiImpl.kt src/main/kotlin/org/openapitools/server/api/api/PetApiImpl.kt
src/main/kotlin/org/openapitools/server/api/api/PetStoreModule.kt src/main/kotlin/org/openapitools/server/api/api/PetStoreModule.kt
src/main/kotlin/org/openapitools/server/api/api/StoreApi.kt src/main/kotlin/org/openapitools/server/api/api/StoreApi.kt
src/main/kotlin/org/openapitools/server/api/api/StoreApiController.kt src/main/kotlin/org/openapitools/server/api/api/StoreApiAction.kt
src/main/kotlin/org/openapitools/server/api/api/StoreApiImpl.kt src/main/kotlin/org/openapitools/server/api/api/StoreApiImpl.kt
src/main/kotlin/org/openapitools/server/api/api/UserApi.kt src/main/kotlin/org/openapitools/server/api/api/UserApi.kt
src/main/kotlin/org/openapitools/server/api/api/UserApiController.kt src/main/kotlin/org/openapitools/server/api/api/UserApiAction.kt
src/main/kotlin/org/openapitools/server/api/api/UserApiImpl.kt src/main/kotlin/org/openapitools/server/api/api/UserApiImpl.kt
src/main/kotlin/org/openapitools/server/api/model/Category.kt src/main/kotlin/org/openapitools/server/api/model/Category.kt
src/main/kotlin/org/openapitools/server/api/model/ModelApiResponse.kt src/main/kotlin/org/openapitools/server/api/model/ModelApiResponse.kt

View File

@ -9,7 +9,7 @@ version = "1.0.0-SNAPSHOT"
dependencies { dependencies {
implementation("jakarta.validation:jakarta.validation-api:3.1.1") implementation("jakarta.validation:jakarta.validation-api:3.1.1")
implementation("com.squareup.misk:misk:2025.03.17.160337-2c6953c") implementation("com.squareup.misk:misk:2025.04.02.195630-a61d550")
//implementation("com.squareup.wire:wire-runtime:5.2.1") //implementation("com.squareup.wire:wire-runtime:5.2.1")
testImplementation("com.squareup.misk:misk-testing:2025.02.11.123913-8a41324") testImplementation("com.squareup.misk:misk-testing:2025.02.11.123913-8a41324")

View File

@ -395,6 +395,6 @@ Name | Type | Description | Notes
### HTTP request headers ### HTTP request headers
- **Content-Type**: MediaTypes.APPLICATION_OCTETSTREAM /* unknown -> multipart/form-data */ - **Content-Type**: MediaTypes.FORM_DATA
- **Accept**: MediaTypes.APPLICATION_JSON - **Accept**: MediaTypes.APPLICATION_JSON

View File

@ -31,10 +31,10 @@ import org.openapitools.server.api.model.ModelApiResponse
import org.openapitools.server.api.model.Pet import org.openapitools.server.api.model.Pet
/** /**
* Generated file, please change PetApiController. * Generated file, please change PetApiImpl.
*/ */
@Singleton @Singleton
class PetApiController @Inject constructor( class PetApiAction @Inject constructor(
private val petApi: PetApi private val petApi: PetApi
) : WebAction, PetApi { ) : WebAction, PetApi {
@ -97,7 +97,7 @@ class PetApiController @Inject constructor(
@Post("/pet/{petId}/uploadImage") @Post("/pet/{petId}/uploadImage")
@Description("uploads an image") @Description("uploads an image")
@RequestContentType(MediaTypes.APPLICATION_OCTETSTREAM /* unknown -> multipart/form-data */ ) @RequestContentType(MediaTypes.FORM_DATA)
@ResponseContentType(MediaTypes.APPLICATION_JSON) @ResponseContentType(MediaTypes.APPLICATION_JSON)
@LogRequestResponse(bodySampling = 1.0, errorBodySampling = 1.0) @LogRequestResponse(bodySampling = 1.0, errorBodySampling = 1.0)
override fun uploadFile(@PathParam("petId") petId: kotlin.Long, @QueryParam(value = "additionalMetadata") additionalMetadata: kotlin.String? , @Valid file: HttpCall): ModelApiResponse { override fun uploadFile(@PathParam("petId") petId: kotlin.Long, @QueryParam(value = "additionalMetadata") additionalMetadata: kotlin.String? , @Valid file: HttpCall): ModelApiResponse {

View File

@ -3,15 +3,15 @@ package org.openapitools.server.api.api
import misk.inject.KAbstractModule import misk.inject.KAbstractModule
import misk.web.WebActionModule import misk.web.WebActionModule
import jakarta.inject.Singleton import jakarta.inject.Singleton
import org.openapitools.server.api.api.PetApiController import org.openapitools.server.api.api.PetApiAction
import org.openapitools.server.api.api.StoreApiController import org.openapitools.server.api.api.StoreApiAction
import org.openapitools.server.api.api.UserApiController import org.openapitools.server.api.api.UserApiAction
@Singleton @Singleton
class PetStoreModule : KAbstractModule() { class PetStoreModule : KAbstractModule() {
override fun configure() { override fun configure() {
install(WebActionModule.create<PetApiController>()) install(WebActionModule.create<PetApiAction>())
install(WebActionModule.create<StoreApiController>()) install(WebActionModule.create<StoreApiAction>())
install(WebActionModule.create<UserApiController>()) install(WebActionModule.create<UserApiAction>())
} }
} }

View File

@ -30,10 +30,10 @@ import misk.web.mediatype.MediaTypes
import org.openapitools.server.api.model.Order import org.openapitools.server.api.model.Order
/** /**
* Generated file, please change StoreApiController. * Generated file, please change StoreApiImpl.
*/ */
@Singleton @Singleton
class StoreApiController @Inject constructor( class StoreApiAction @Inject constructor(
private val storeApi: StoreApi private val storeApi: StoreApi
) : WebAction, StoreApi { ) : WebAction, StoreApi {

View File

@ -30,10 +30,10 @@ import misk.web.mediatype.MediaTypes
import org.openapitools.server.api.model.User import org.openapitools.server.api.model.User
/** /**
* Generated file, please change UserApiController. * Generated file, please change UserApiImpl.
*/ */
@Singleton @Singleton
class UserApiController @Inject constructor( class UserApiAction @Inject constructor(
private val userApi: UserApi private val userApi: UserApi
) : WebAction, UserApi { ) : WebAction, UserApi {

View File

@ -19,7 +19,7 @@ internal class PetApiTest {
@Inject private lateinit var petApi: PetApi @Inject private lateinit var petApi: PetApi
/** /**
* To test PetApiController.addPet * To test PetApiAction.addPet
*/ */
@Test @Test
fun `should handle addPet`() { fun `should handle addPet`() {
@ -28,7 +28,7 @@ internal class PetApiTest {
} }
/** /**
* To test PetApiController.deletePet * To test PetApiAction.deletePet
*/ */
@Test @Test
fun `should handle deletePet`() { fun `should handle deletePet`() {
@ -38,7 +38,7 @@ internal class PetApiTest {
} }
/** /**
* To test PetApiController.findPetsByStatus * To test PetApiAction.findPetsByStatus
*/ */
@Test @Test
fun `should handle findPetsByStatus`() { fun `should handle findPetsByStatus`() {
@ -47,7 +47,7 @@ internal class PetApiTest {
} }
/** /**
* To test PetApiController.findPetsByTags * To test PetApiAction.findPetsByTags
*/ */
@Test @Test
fun `should handle findPetsByTags`() { fun `should handle findPetsByTags`() {
@ -56,7 +56,7 @@ internal class PetApiTest {
} }
/** /**
* To test PetApiController.getPetById * To test PetApiAction.getPetById
*/ */
@Test @Test
fun `should handle getPetById`() { fun `should handle getPetById`() {
@ -65,7 +65,7 @@ internal class PetApiTest {
} }
/** /**
* To test PetApiController.updatePet * To test PetApiAction.updatePet
*/ */
@Test @Test
fun `should handle updatePet`() { fun `should handle updatePet`() {
@ -74,7 +74,7 @@ internal class PetApiTest {
} }
/** /**
* To test PetApiController.updatePetWithForm * To test PetApiAction.updatePetWithForm
*/ */
@Test @Test
fun `should handle updatePetWithForm`() { fun `should handle updatePetWithForm`() {
@ -85,7 +85,7 @@ internal class PetApiTest {
} }
/** /**
* To test PetApiController.uploadFile * To test PetApiAction.uploadFile
*/ */
@Test @Test
fun `should handle uploadFile`() { fun `should handle uploadFile`() {

View File

@ -18,7 +18,7 @@ internal class StoreApiTest {
@Inject private lateinit var storeApi: StoreApi @Inject private lateinit var storeApi: StoreApi
/** /**
* To test StoreApiController.deleteOrder * To test StoreApiAction.deleteOrder
*/ */
@Test @Test
fun `should handle deleteOrder`() { fun `should handle deleteOrder`() {
@ -27,7 +27,7 @@ internal class StoreApiTest {
} }
/** /**
* To test StoreApiController.getInventory * To test StoreApiAction.getInventory
*/ */
@Test @Test
fun `should handle getInventory`() { fun `should handle getInventory`() {
@ -35,7 +35,7 @@ internal class StoreApiTest {
} }
/** /**
* To test StoreApiController.getOrderById * To test StoreApiAction.getOrderById
*/ */
@Test @Test
fun `should handle getOrderById`() { fun `should handle getOrderById`() {
@ -44,7 +44,7 @@ internal class StoreApiTest {
} }
/** /**
* To test StoreApiController.placeOrder * To test StoreApiAction.placeOrder
*/ */
@Test @Test
fun `should handle placeOrder`() { fun `should handle placeOrder`() {

View File

@ -18,7 +18,7 @@ internal class UserApiTest {
@Inject private lateinit var userApi: UserApi @Inject private lateinit var userApi: UserApi
/** /**
* To test UserApiController.createUser * To test UserApiAction.createUser
*/ */
@Test @Test
fun `should handle createUser`() { fun `should handle createUser`() {
@ -27,7 +27,7 @@ internal class UserApiTest {
} }
/** /**
* To test UserApiController.createUsersWithArrayInput * To test UserApiAction.createUsersWithArrayInput
*/ */
@Test @Test
fun `should handle createUsersWithArrayInput`() { fun `should handle createUsersWithArrayInput`() {
@ -36,7 +36,7 @@ internal class UserApiTest {
} }
/** /**
* To test UserApiController.createUsersWithListInput * To test UserApiAction.createUsersWithListInput
*/ */
@Test @Test
fun `should handle createUsersWithListInput`() { fun `should handle createUsersWithListInput`() {
@ -45,7 +45,7 @@ internal class UserApiTest {
} }
/** /**
* To test UserApiController.deleteUser * To test UserApiAction.deleteUser
*/ */
@Test @Test
fun `should handle deleteUser`() { fun `should handle deleteUser`() {
@ -54,7 +54,7 @@ internal class UserApiTest {
} }
/** /**
* To test UserApiController.getUserByName * To test UserApiAction.getUserByName
*/ */
@Test @Test
fun `should handle getUserByName`() { fun `should handle getUserByName`() {
@ -63,7 +63,7 @@ internal class UserApiTest {
} }
/** /**
* To test UserApiController.loginUser * To test UserApiAction.loginUser
*/ */
@Test @Test
fun `should handle loginUser`() { fun `should handle loginUser`() {
@ -73,7 +73,7 @@ internal class UserApiTest {
} }
/** /**
* To test UserApiController.logoutUser * To test UserApiAction.logoutUser
*/ */
@Test @Test
fun `should handle logoutUser`() { fun `should handle logoutUser`() {
@ -81,7 +81,7 @@ internal class UserApiTest {
} }
/** /**
* To test UserApiController.updateUser * To test UserApiAction.updateUser
*/ */
@Test @Test
fun `should handle updateUser`() { fun `should handle updateUser`() {