レトロフィット入門

レトロフィットの概要

1. 概要

Retrofitは、Square(DaggerOkhttp)によって開発されたAndroidおよびJava用のタイプセーフなHTTPクライアントです。

この記事では、Retrofitの最も興味深い機能に焦点を当てて、その使用方法を説明します。 特に、同期APIと非同期API、認証、ロギング、およびいくつかの優れたモデリング手法でそれを使用する方法について説明します。

2. サンプルのセットアップ

まず、RetrofitライブラリとGsonコンバーターを追加します。


    com.squareup.retrofit2
    retrofit
    2.3.0


    com.squareup.retrofit2
    converter-gson
    2.3.0

最新バージョンについては、Maven CentralリポジトリのRetrofitconverter-gsonを確認してください。

3. APIモデリング

Retrofitは、RESTエンドポイントをJavaインターフェースとしてモデル化し、非常に簡単に理解して使用できるようにします。

GitHubからuser APIをモデル化します。これには、これをJSON形式で返すGETエンドポイントがあります。

{
  login: "mojombo",
  id: 1,
  url: "https://api.github.com/users/mojombo",
  ...
}

レトロフィットは、ベースURLをモデリングし、インターフェイスがRESTエンドポイントからエンティティを返すようにすることで機能します。

簡単にするために、値を受け取ったときに値を取得するUserクラスをモデル化することにより、JSONのごく一部を取得します。

public class User {
    private String login;
    private long id;
    private String url;
    // ...

    // standard getters an setters

}

この例では、プロパティのサブセットのみを取得していることがわかります。 Retrofit won’t complain about missing properties – since it only maps what we need、JSONにないプロパティを追加しても文句はありません。

これで、インターフェイスモデリングに移行して、Retrofitアノテーションの一部を説明できます。

public interface UserService {

    @GET("/users")
    public Call> getUsers(
      @Query("per_page") int per_page,
      @Query("page") int page);

    @GET("/users/{username}")
    public Call getUser(@Path("username") String username);
}

ツールが機能する実装を生成するには、注釈付きで提供されるメタデータで十分です。

@GETアノテーションは、どのHTTPメソッドをどのリソースで使用するかをクライアントに通知します。たとえば、「https://api.github.com」のベースURLを指定すると、リクエストが「https: //api.github.com/users」。

相対URLtells Retrofit that it is an absolute path on the host.の先頭の「/」

もう1つの注意点は、完全にオプションの@Queryパラメータを使用していることです。これは、必要がない場合はnullとして渡すことができ、値がない場合はツールがこれらのパラメータを無視します。

最後になりましたが、@Pathを使用すると、パスで使用したマークアップの代わりに配置されるパスパラメーターを指定できます。

4. Synchronous/Asynchronous API

HTTPリクエストコールを作成するには、最初にRetrofitオブジェクトを作成する必要があります。

OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
Retrofit retrofit = new Retrofit.Builder()
  .baseUrl("https://api.github.com/")
  .addConverterFactory(GsonConverterFactory.create())
  .client(httpClient.build())
  .build();

Retrofitは、必要なオブジェクトを構築するための便利なビルダーを提供します。 It needs the base URL which is going to be used for every service call and a converter factory –送信するデータの解析と取得する応答を処理します。

この例では、GsonConverterFactoryを使用します。これにより、JSONデータが前に定義したUserクラスにマップされます。

ファクトリが異なれば目的も異なることに注意することが重要です。そのため、ファクトリをXMLやプロトバッファに使用したり、カスタムプロトコル用に作成したりすることもできることに注意してください。 すでに実装されているファクトリのリストについては、hereを参照してください。

最後の依存関係はOKHttpClientです。これはAndroidおよびJavaアプリケーション用のHTTPおよびHTTP / 2クライアントです。 これにより、サーバーへの接続と情報の送信および取得が処理されます。 また、すべての呼び出しにヘッダーとインターセプターを追加することもできます。これについては、認証セクションで説明します。

Retrofitオブジェクトができたので、サービスコールを作成できます。これを同期的に行う方法を見てみましょう。

UserService service = retrofit.create(UserService.class);
Call callSync = service.getUser("eugenp");

try {
    Response response = callSync.execute();
    User user = response.body();
} catch (Exception ex) { ... }

ここで、以前の注釈に基づいて、要求を行うために必要なコードを注入することにより、Retrofitがサービスインターフェイスの構築をどのように処理するかを確認できます。

その後、GitHub APIへのリクエストの実行に使用されるCall<User>オブジェクトを取得します。 The most important method here is execute,は、呼び出しを同期的に実行するために使用され、データの転送中に現在のスレッドをブロックします。

呼び出しが正常に実行された後、GsonConverterFactoryのおかげで、応答の本文(すでにユーザーオブジェクト上にある)を取得できます。

同期呼び出しは非常に簡単ですが、通常、非ブロッキング非同期要求を使用します。

UserService service = retrofit.create(UserService.class);
Call callAsync = service.getUser("eugenp");

callAsync.enqueue(new Callback() {
    @Override
    public void onResponse(Call call, Response response) {
        User user = response.body();
    }

    @Override
    public void onFailure(Call call, Throwable throwable) {
        System.out.println(throwable);
    }
});

ここで、executeメソッドの代わりに、enqueueメソッドを使用します。これは、リクエストの成功または失敗を処理するためのパラメーターとしてCallback<User>interfaceを取ります。 これは別のスレッドで実行されることに注意してください。

呼び出しが正常に終了した後、以前と同じ方法で本体を取得できます。

5. 再利用可能なServiceGeneratorクラスの作成

Retrofitオブジェクトの作成方法とAPIの使用方法を確認したので、ビルダーを何度も作成し続けたくないことがわかります。

必要なのは、このオブジェクトを一度作成して、アプリケーションの存続期間中再利用できるようにする再利用可能なクラスです。

public class GitHubServiceGenerator {

    private static final String BASE_URL = "https://api.github.com/";

    private static Retrofit.Builder builder
      = new Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create());

    private static Retrofit retrofit = builder.build();

    private static OkHttpClient.Builder httpClient
      = new OkHttpClient.Builder();

    public static  S createService(Class serviceClass) {
        return retrofit.create(serviceClass);
    }
}

Retrofitオブジェクトを作成するすべてのロジックは、このGitHubServiceGeneratorクラスに移動されました。これにより、コードの繰り返しを停止する持続可能なクライアントクラスになります。

使用方法の簡単な例を次に示します。

UserService service
  = GitHubServiceGenerator.createService(UserService.class);

たとえば、RepositoryService,を作成する場合、このクラスを再利用して作成を簡素化できます。

In the next section、それを拡張し、認証機能を追加します。

6. 認証

ほとんどのAPIには、アクセスを保護するための何らかの認証があります。

以前のジェネレータークラスを考慮して、Authorizationヘッダーを持つJWTトークンを受け取るcreateserviceメソッドを追加します。

public static  S createService(Class serviceClass, final String token ) {
   if ( token != null ) {
       httpClient.interceptors().clear();
       httpClient.addInterceptor( chain -> {
           Request original = chain.request();
           Request request = original.newBuilder()
             .header("Authorization", token)
             .build();
           return chain.proceed(request);
       });
       builder.client(httpClient.build());
       retrofit = builder.build();
   }
   return retrofit.create(serviceClass);
}

リクエストにヘッダーを追加するには、OkHttpのインターセプター機能を使用する必要があります。これを行うには、以前に定義したビルダーを使用し、Retrofitオブジェクトを再構築します。

これは単純な認証の例ですが、インターセプターを使用すると、OAuth、ユーザー/パスワードなどの認証を使用できます。

7. ロギング

このセクションでは、ロギング機能のGitHubServiceGeneratorをさらに拡張します。これは、すべてのプロジェクトのデバッグ目的で非常に重要です。

インターセプターに関する以前の知識を使用しますが、追加の依存関係が必要です。これは、OkHttpのHttpLoggingInterceptorであり、pom.xmlに追加します。


    com.squareup.okhttp3
    logging-interceptor
    3.9.0

ここで、GitHubServiceGeneratorクラスを拡張しましょう:

public class GitHubServiceGenerator {

    private static final String BASE_URL = "https://api.github.com/";

    private static Retrofit.Builder builder
      = new Retrofit.Builder()
        .baseUrl(BASE_URL)
        .addConverterFactory(GsonConverterFactory.create());

    private static Retrofit retrofit = builder.build();

    private static OkHttpClient.Builder httpClient
      = new OkHttpClient.Builder();

    private static HttpLoggingInterceptor logging
      = new HttpLoggingInterceptor()
        .setLevel(HttpLoggingInterceptor.Level.BASIC);

    public static  S createService(Class serviceClass) {
        if (!httpClient.interceptors().contains(logging)) {
            httpClient.addInterceptor(logging);
            builder.client(httpClient.build());
            retrofit = builder.build();
        }
        return retrofit.create(serviceClass);
    }

    public static  S createService(Class serviceClass, final String token) {
        if (token != null) {
            httpClient.interceptors().clear();
            httpClient.addInterceptor( chain -> {
                Request original = chain.request();
                Request.Builder builder1 = original.newBuilder()
                  .header("Authorization", token);
                Request request = builder1.build();
                return chain.proceed(request);
            });
            builder.client(httpClient.build());
            retrofit = builder.build();
        }
        return retrofit.create(serviceClass);
    }
}

これがクラスの最終形式であり、HttpLoggingInterceptorを追加した方法を確認できます。これを基本ログに設定します。これにより、リクエストの作成にかかった時間、エンドポイント、すべてのステータスがログに記録されます。リクエストなど

インターセプターが存在するかどうかを確認する方法を確認することが重要です。これにより、誤ってインターセプターを2回追加することはありません。

8. 結論

この広範なガイドでは、Sync / Async API、モデリング、認証、およびログ記録のベストプラクティスに焦点を当てて、優れたRetrofitライブラリを検討しました。

ライブラリは非常に複雑で便利な方法で使用できます。 RxJavaの高度なユースケースについては、this tutorialをご覧ください。

そして、いつものように、ソースコードはover on GitHubで見つけることができます。