Help us understand the problem. What is going on with this article?

[Android] WebAPIでのサーバー接続

Androidアプリから、APIでWebサーバーへアクセスするライブラリ sankosc/webapi-clientの紹介となります。Kotlinです。

このライブラリの特徴は
- jsonの解析はKotlinx Jsonで自動で行う。データ構造だけ定義します。
- 通信のリトライと、AccessTokenのRefreshの処理を半自動で行います。
- バックグラウンドにて実行します。
- 通信成功、失敗の処理をイベントとして渡します。そのイベントはUIスレッドで呼び出されます。

インストール方法

Kotolinx Jsonを使用しますので、そのインストールも併せて行います。

プロジェクトのbundle.gradleとアプリのbundle.gradleを編集

bundle.gradle(Project)
dependencies {
    classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
}
bundle.gradle(app)
apply plugin: 'kotlinx-serialization'

dependencies {
    implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:0.20.0"
    implementation 'jp.co.sankosc:webapi-client:1.0.2'
}

パーミッション追加

AndroidManifest.xmlにパーミッションを追加します。

AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />

データ定義

データ定義はKotolinx Jsonで行います。
詳しい定義方法はこちらをご参照ください:Kotolinx Json

sample
import kotlinx.serialization.*

@Serializable
data class Message(
    val message: String?
)

@Serializable
data class Login(
    val email: String,
    val password: String
)

@Serializable
data class Token(
    @SerialName("access_token")
    val accessToken: String
)

Get

Genericでデータ構造を指定。APIのURLと成功、失敗時のイベントハンドラを引数で渡します。
成功時には、イベントハンドラに指定した構造のデータが渡されます。

sample
val url = "https://develop.sankosc.co.jp/apitest/api/hello"
val client = WebApiClient()
client.get<Message>(url, {
    // Success
    println(it.message)
}, {
    // Error
    it.printStackTrace()
})

Post

Genericでデータ構造を指定。APIのURLと送信データ、成功、失敗時のイベントハンドラを引数で渡します。
成功時には、イベントハンドラに指定した構造のデータが渡されます。

sample
val url = "https://develop.sankosc.co.jp/apitest/api/echo"
val client = WebApiClient()
client.post<Message, Message>(url, Message("post data"), {
    // Success
    println(it.message)
}, {
    // Error
    it.printStackTrace()
})

エラー処理

失敗時には、発生した例外がハンドラに渡されます。
サーバーエラーの場合は、WebApiClientExceptionが渡されます。
WebApiClientExceptionは、サーバーのステータスコードを含みます。
例外は、Exceptionとして渡されるので、必要であればキャストして使用します。

例)エラー処理
client.get<Message>(url, {
}, {
    // Error
    if (it is WebApiClientException) {
        println(it.code)
    }
})

認証APIへのアクセス

Login処理などで取得したAccessトークンをインスタンスに設定してGet, Postを使用します。
そうするとヘッダにAuthorization: Bearer [Access Token]を付けてサーバーにアクセスするようになります。

例)ログイン処理
val url = "https://develop.sankosc.co.jp/apitest/api/login"
val client = WebApiClient()
val data = Login("sample@sankosc.co.jp", "sample123")
client.post<Login, Token>(url, data, {
    client.accessToken = it.accessToken
}, {
    it.printStackTrace()
})

AccessTokenは、アプリ起動時などに保存しておいたものをコンストラクタにて設定することもできます。

sample
val client = WebApiClient(accessToken = "[保存しておいたトークン]")

認証エラーの処理

認証エラーの処理は、WebApiClientインスタンス生成時にコンストラクタを通して設定します。

sample
val client = WebApiClient(handleAuthFail = {
    // 認証エラー処理
})

AccessTokenのリフレッシュ

AccessTokenのリフレッシュの処理は、WebApiClientインスタンス生成時にコンストラクタを通して設定します。設定したハンドラは、サーバーからステータスコード401が返されたときに呼び出されます。

このハンドラ(handleTokenExpired)は、引数を2つもちます。呼び出し元のWebApiClientインスタンスとリフレッシュしたトークンを渡すonRefreshed関数です。onRefreshed関数は、呼び出されたときに、認証切れになる直前に呼ばれていたAPIを再度自動で呼び出します。

トークンリフレッシュの例
val client = WebApiClient(handleTokenExpired= {client, onRefreshed ->
    // トークンリフレッシュ処理
    val url = "https://develop.sankosc.co.jp/apitest/api/refresh"
    client.refresh<Token>(url, {
        onRefreshed(it.accessToken)
    }, {
        it.printStackTrace()
    })
})

トークンのリフレッシュには、通常のget, postメソッドではなくrefreshメソッドを使います。
get, postメソッドとrefreshメソッドは、機能はまったく一緒ですが認証エラー時の処理が違います。

おしまい

もしご興味ある方は、こちらに他のパラメータも記載していますのでご参照ください。
GitHub: https://github.com/sankosc/webapi-client-android

また確認用のAPIサーバーを準備していますので、こちらで試して頂けたら幸いです。
APIサーバー https://develop.sankosc.co.jp/apitest/

ありがとうございました。

nozaki-sankosc
東京都中央区にある三幸システムの野崎です。 Android, iOS, PHPなどのライブラリを公開していきたいと思います。
https://www.sankosc.co.jp
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした