Search code examples
restkotlinswaggerswagger-codegen

Modify contentHeaders of Swagger Codegen methods in kotlin


I'm using swagger codegen for my REST API calls. For authentication purposes i need to send a session-token within the headers of every request. This is currently done, via APIClients' defaultHeaders

open class ApiClient(val baseUrl: String) {
    companion object {
        ...
        @JvmStatic
        var defaultHeaders: Map<String, String> by ApplicationDelegates.setOnce(mapOf(ContentType to JsonMediaType, Accept to JsonMediaType))
        ...
    }
}

The way swagger generates the code, these headers can only be modified once.

ApiClient.defaultHeaders += mapOf("Authorization" to userSession!!.idToken.jwtToken)

The problem with this is, that i cannot change the token (e.g. because another user logged in within the application lifetime). Looking deeper into the generated code, before each request is sent, a merge of both defaultHeaders and requestConfig.headers (=contentHeaders) is being made.

inline protected fun <reified T: Any?> request(requestConfig: RequestConfig, body : Any? = null): ApiInfrastructureResponse<T?> {
    ...
    val headers = defaultHeaders + requestConfig.headers
    ...
}

The given RequestConfig object comes from every api call. However it is not possible to change these contentHeaders. Also they are empty by default.

fun someAPIRestCall(someParam: kotlin.String) : Unit {
    val localVariableBody: kotlin.Any? = type
    val localVariableQuery: MultiValueMap = mapOf()

    val contentHeaders: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf() // THESE WILL BE MERGED WITH defaultHeaders
    val acceptsHeaders: kotlin.collections.Map<kotlin.String,kotlin.String> = mapOf("Accept" to "application/json")
    val localVariableHeaders: kotlin.collections.MutableMap<kotlin.String,kotlin.String> = mutableMapOf()
    localVariableHeaders.putAll(contentHeaders)
    localVariableHeaders.putAll(acceptsHeaders)

    val localVariableConfig = RequestConfig(
        RequestMethod.POST,
        "someEndpointURL"),
        query = localVariableQuery,
        headers = localVariableHeaders // THESE WILL BE MERGED WITH defaultHeaders
    )
    val response = request<Unit>(
        localVariableConfig,
        localVariableBody
    )
    ...
}

Is it possible to tell swagger-codegen to include some kind of parameter to the generated method signature to add values to those contentHeaders?

EDIT:

This is the current code-gen call within my gradle build chain

task generateSwagger(type: JavaExec) {
    main = "-jar"
    args "swagger-codegen-cli-2.4.7.jar", "generate", "-i", "./swagger_core.yml", "-l", "kotlin", "-o", "./tmp/RestApi", "--type-mappings", "number=kotlin.Long"
}

Solution

  • By now, i found a solution, that is more of a hack, but it works.

    As i am using gradle to build the app, i introduced a task, that changes the generated swagger code, before it actually compiles.

    task editAPISources {
        def token = "Map<String, String> by ApplicationDelegates.setOnce(mapOf(ContentType to JsonMediaType, Accept to JsonMediaType))"
        def value = "MutableMap<String, String> = mutableMapOf(ContentType to JsonMediaType, Accept to JsonMediaType)"
        def file = new File("./app/tmp/RestApi/src/main/kotlin/io/swagger/client/infrastructure/ApiClient.kt")
        def newConfig = file.text.replace(token, value)
        file.write newConfig
    }
    

    The result is a now changeable header :=

    @JvmStatic
    var defaultHeaders: MutableMap<String, String> = mutableMapOf(ContentType to JsonMediaType, Accept to JsonMediaType)