user866364
user866364

Reputation:

Kotlin - chain of scope functions

I'm new to Kotlin language and I would like to know if it's a good practice have a chain of scope functions. As example, I'm writing a function that calls some API (an utilitary function), parse the string response to specific object, do a small verification and return an object.

Is a good practice have a chain of scope functions like this code above?

    fun execRequest(endpoint: String, method: String = "GET", body: String? = ""): String =
            defaultHttpRequestBuilder()
                    .uri(URI.create(endpoint))
                    .method(method, HttpRequest.BodyPublishers.ofString(body))
                    .header("Content-Type", "application/x-www-form-urlencoded")
                    .build()
                    .run { httpClient.send(this, HttpResponse.BodyHandlers.ofString()) }
                    .let { it.body() }

    fun processLoginRequest(challenge: String) =
            execRequest(buildEndpoint("login", challenge))
                    .let {
                        mapper.readValue<LoginResponse>(it)
                    }
                    .let {
                        val authSituation = Auth(it.skip, it.challenge)
                        if (it.skip) {
                            val acceptResponse = acceptLoginRequest(challenge, it.subject)
                            authSituation.redirectTo = acceptResponse.redirectTo
                        }
                        authSituation
                    }

This code looks awful in my opinion. Is there another way to write it in a "Kotlin way"?

Upvotes: 0

Views: 1074

Answers (1)

Tenfour04
Tenfour04

Reputation: 93571

I think this question is likely to be closed due to answers being a matter of opinion, but since you asked about my comment, here is how you could break up the first function.

fun execRequest(endpoint: String, method: String = "GET", body: String? = ""): String {
    val request = defaultHttpRequestBuilder()
        .uri(URI.create(endpoint))
        .method(method, HttpRequest.BodyPublishers.ofString(body))
        .header("Content-Type", "application/x-www-form-urlencoded")
        .build()
    val response = httpClient.send(request, HttpResponse.BodyHandlers.ofString())
    return response.body()
}

I might break up the second function like this

fun processLoginRequest(challenge: String): Auth {
    val httpResponse = execRequest(buildEndpoint("login", challenge))
    val loginResponse: LoginResponse = mapper.readValue(httpResponse)
    return Auth(loginResponse.skip, loginResponse.challenge)
        .apply {
            if (loginResponse.skip) 
                redirectTo = acceptLoginRequest(challenge, it.subject).redirectTo
        }
}

Upvotes: 2

Related Questions