Repository: cjbooms/fabrikt (kotlin)

Issue:
Use operationId in clients as well
Follow-up for #111: for the sake of consistency, it seems sensible to use the `operationId` in clients as well, not just controllers. It looks like right now, the name is generated based on the path (`/example-path-1` -> `getExamplePath1`).

Pull request:
ISSUE-119: Support naming http client methods after the operationId

Closes #119

Patch:
diff --git a/src/main/kotlin/com/cjbooms/fabrikt/generators/GeneratorUtils.kt b/src/main/kotlin/com/cjbooms/fabrikt/generators/GeneratorUtils.kt
index a431639b..1aca5b62 100644
--- a/src/main/kotlin/com/cjbooms/fabrikt/generators/GeneratorUtils.kt
+++ b/src/main/kotlin/com/cjbooms/fabrikt/generators/GeneratorUtils.kt
@@ -2,6 +2,7 @@ package com.cjbooms.fabrikt.generators
 
 import com.cjbooms.fabrikt.generators.model.JacksonModelGenerator.Companion.toModelType
 import com.cjbooms.fabrikt.model.KotlinTypeInfo
+import com.cjbooms.fabrikt.util.NormalisedString.camelCase
 import com.reprezen.kaizen.oasparser.model3.MediaType
 import com.reprezen.kaizen.oasparser.model3.Operation
 import com.reprezen.kaizen.oasparser.model3.Parameter
@@ -95,7 +96,7 @@ object GeneratorUtils {
             this.addParameter(parameterSpec)
     }
 
-    fun functionName(resource: String, verb: String) = "$verb $resource".toKCodeName()
+    fun functionName(op: Operation, resource: String, verb: String) = op.operationId?.camelCase() ?: "$verb $resource".toKCodeName()
 
     fun Schema.toVarName() = this.name?.toKCodeName() ?: this.toClassName().simpleName.toKCodeName()
 
diff --git a/src/main/kotlin/com/cjbooms/fabrikt/generators/client/OkHttpEnhancedClientGenerator.kt b/src/main/kotlin/com/cjbooms/fabrikt/generators/client/OkHttpEnhancedClientGenerator.kt
index 3da6ef1a..b8a53086 100644
--- a/src/main/kotlin/com/cjbooms/fabrikt/generators/client/OkHttpEnhancedClientGenerator.kt
+++ b/src/main/kotlin/com/cjbooms/fabrikt/generators/client/OkHttpEnhancedClientGenerator.kt
@@ -51,7 +51,7 @@ class OkHttpEnhancedClientGenerator(
             val funSpecs: List<FunSpec> = paths.flatMap { (resource, path) ->
                 path.operations.map { (verb, operation) ->
                     FunSpec
-                        .builder(functionName(resource, verb))
+                        .builder(functionName(operation, resource, verb))
                         .addModifiers(KModifier.PUBLIC)
                         .addAnnotation(
                             AnnotationSpec.builder(Throws::class)
@@ -216,7 +216,7 @@ class Resilience4jClientOperationStatement(
             )
         )
 
-        this.add("apiClient.%N(%L)", functionName(resource, verb), params.flatten().joinToString(",") { it.name })
+        this.add("apiClient.%N(%L)", functionName(operation, resource, verb), params.flatten().joinToString(",") { it.name })
         return this
     }
 }
diff --git a/src/main/kotlin/com/cjbooms/fabrikt/generators/client/OkHttpSimpleClientGenerator.kt b/src/main/kotlin/com/cjbooms/fabrikt/generators/client/OkHttpSimpleClientGenerator.kt
index c229d2cc..1c55e213 100644
--- a/src/main/kotlin/com/cjbooms/fabrikt/generators/client/OkHttpSimpleClientGenerator.kt
+++ b/src/main/kotlin/com/cjbooms/fabrikt/generators/client/OkHttpSimpleClientGenerator.kt
@@ -51,7 +51,7 @@ class OkHttpSimpleClientGenerator(
             val funcSpecs: List<FunSpec> = paths.flatMap { (resource, path) ->
                 path.operations.map { (verb, operation) ->
                     FunSpec
-                        .builder(functionName(resource, verb))
+                        .builder(functionName(operation, resource, verb))
                         .addModifiers(KModifier.PUBLIC)
                         .addKdoc(operation.toKdoc())
                         .addAnnotation(


Test patch:
diff --git a/src/test/resources/examples/okHttpClient/api.yaml b/src/test/resources/examples/okHttpClient/api.yaml
index 34c712eb..61d26710 100644
--- a/src/test/resources/examples/okHttpClient/api.yaml
+++ b/src/test/resources/examples/okHttpClient/api.yaml
@@ -60,6 +60,7 @@ paths:
             \ Indicates that the resource as described by the passed etag value has\
             \ not changed"
     head:
+      operationId: headOperationIdExample
       summary: "HEAD example path 2"
       parameters:
         - $ref: "#/components/parameters/PathParam"
diff --git a/src/test/resources/examples/okHttpClient/client/ApiClient.kt b/src/test/resources/examples/okHttpClient/client/ApiClient.kt
index 067f05f3..60875666 100644
--- a/src/test/resources/examples/okHttpClient/client/ApiClient.kt
+++ b/src/test/resources/examples/okHttpClient/client/ApiClient.kt
@@ -141,7 +141,7 @@ class ExamplePath2Client(
      * @param ifNoneMatch The RFC7232 If-None-Match header field
      */
     @Throws(ApiException::class)
-    fun headExamplePath2PathParam(
+    fun headOperationIdExample(
         pathParam: String,
         queryParam3: Boolean?,
         ifNoneMatch: String?,
diff --git a/src/test/resources/examples/okHttpClient/client/ApiService.kt b/src/test/resources/examples/okHttpClient/client/ApiService.kt
index a5149b98..0a257c15 100644
--- a/src/test/resources/examples/okHttpClient/client/ApiService.kt
+++ b/src/test/resources/examples/okHttpClient/client/ApiService.kt
@@ -86,14 +86,14 @@ class ExamplePath2Service(
         }
 
     @Throws(ApiException::class)
-    fun headExamplePath2PathParam(
+    fun headOperationIdExample(
         pathParam: String,
         queryParam3: Boolean?,
         ifNoneMatch: String?,
         additionalHeaders: Map<String, String> = emptyMap()
     ): ApiResponse<Unit?> =
         withCircuitBreaker(circuitBreakerRegistry, circuitBreakerName) {
-            apiClient.headExamplePath2PathParam(pathParam, queryParam3, ifNoneMatch, additionalHeaders)
+            apiClient.headOperationIdExample(pathParam, queryParam3, ifNoneMatch, additionalHeaders)
         }
 
     @Throws(ApiException::class)