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が立ち上がらなくなりました・・・。
あんまりイケてないのでもうちょっとイケてる感じにしたいです。
型づけするだけだと思うので動作確認取れたら、下の方になおします。