Kotlinで簡単なRESTを叩く SDKを作る

Android 端末用のSDKを作っています。
[Fuel](https://github.com/kittinunf/Fuel)というライブラリをラップしてエンドポイントを叩く関数を作るだけなのですが、この方法、意外と
自作のRESTクライアントを作るときに便利です。
設定はcompanion objectに全部紐づけてしまいます。

```kotlin

import android.content.Context
import com.github.kittinunf.fuel.*
import com.github.kittinunf.fuel.core.*
import com.github.kittinunf.result.Result
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import java.nio.charset.Charset


class TeratailApiClient {
       companion object {

            val jsonParser: JsonParser = JsonParser()
            val url = "http://teratail.com/api/v1"
            var header: MutableMap<String, String> = mutableMapOf()
            var body: JsonObject = JsonObject()
            var error_msg:String? = null
            var error_code: String? = null
            var ACCESS_TOKEN = "any token"

            init{
                for((key,value) in listOf("Authorization" to ACCESS_TOKEN)) {
                    header[key] = value
                }
            }
        }

       @JvmStatic private fun Get(url: String, header: Map<String, String>, query: List<Pair<String, Any?>>, proc: (Any?, Any?, Any?) -> Any?) {
            Fuel.get(url, query).header(header).responseString { request, response, result ->
                proc(request, response, result)
            }
        }

        @JvmStatic private fun resultParseJson(result: Any?): JsonObject {
            var parsed = result as Result<*, *>
            return jsonParser.parse(parsed.get() as String) as JsonObject
        }

        @JvmStatic private fun requestValidate(context: Context, response: Response, result: Result<*, *>) :Boolean{
            try {
                if (response.httpStatusCode == 200) {
                    return true
                } else {
                    //for debug
                    error_msg = ((result as Result.Failure).error as FuelError)
                            .errorData.toString(Charset.defaultCharset())
                    return false
                }
            } catch (e:Exception) {
                //for debug
                error_msg = "error:" + e.message + "]"
                return false
            }
        }

        @JvmStatic private fun getResult(context: Context, response:Any?,result:Any?,func: (Any?, Any?, Any?, Any?) -> Any?) {
            if (requestValidate(context, response as Response, result as Result<*, *>)) {
                func(response, resultParseJson(result), null, null)
            } else {
                func(response, result, error_msg, error_code)
            }
        }

        
        @JvmStatic fun GetQuestions(context: Context, query: List<Pair<String, Any?>> = listOf(), func:(Any?, Any?, Any?, Any?) -> Any?) {
            Get(url + "/questions", header, query){
                req,res,result-> getResult(context, res,result,func)
            }
        }

    }
}
```

使うときはこうします。JSONで後続のレスポンス処理が出来ます。

```kotlin
TeratailApiClient.GetQuestions(this, listOf()){req,res,result,error ->
    if(error != false) {
            //some action
    }
}
```

でも本当は以下のように出来るので、こうしたいなー。

```kotlin
TeratailApiClient.GetQuestions(this, listOf()){req,res,result ->
    when (result) {
            is Result.Failure -> {
              //some action
            }
            is Result.Success -> {
              //some action
            }
    }
}
```
初期化時にapi tokenをセットするようにもしたいなー。
前日にちょうど枠が空いてたのを発見したので、昔書いたコードで、載せれそうなのさっと載せようと思って、４ヶ月ぶりくらいにAndroid Studio開いてバージョンアップしたら、なぜか、AVDが立ち上がらなくなりました・・・。
あんまりイケてないのでもうちょっとイケてる感じにしたいです。
型づけするだけだと思うので動作確認取れたら、下の方になおします。