LoginSignup
5
4

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-12-10

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


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で後続のレスポンス処理が出来ます。

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

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

TeratailApiClient.GetQuestions(this, listOf()){req,res,result ->
    when (result) {
            is Result.Failure -> {
              //some action
            }
            is Result.Success -> {
              //some action
            }
    }
}

初期化時にapi tokenをセットするようにもしたいなー。
前日にちょうど枠が空いてたのを発見したので、昔書いたコードで、載せれそうなのさっと載せようと思って、4ヶ月ぶりくらいにAndroid Studio開いてバージョンアップしたら、なぜか、AVDが立ち上がらなくなりました・・・。
あんまりイケてないのでもうちょっとイケてる感じにしたいです。
型づけするだけだと思うので動作確認取れたら、下の方になおします。

5
4
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4