Androidアプリ開発でretrofit使ってたんですが、そこで躓いた点を備忘録としてまとめておきます
クエリ部分に@Pathを使ってデータを渡せない
そのままですが、例えば下記のように@Queryでクエリパラメータを渡すことがあると思います
@GET("v1/get") fun searchBook( @Query("isbn") isbn: String ): Single<JsonArray>
この場合最終的なURLは {BASE_URL}/v1/get?isbn={isbn} となります これはなんの問題もないです
ただ以下のように書くと怒られます
@GET("v1/get?isbn={isbn}") fun searchBook( @Path("isbn") isbn: String ): Single<JsonArray>
何故かクエリを@Pathで渡そうとするとエラーになります できてもいい気がするんですけどね。なんでなんでしょうか?
ちなみにこんなエラーが出ます
must not have replace block. For dynamic query parameters use @Query.
@Urlオプション使うときはパラメータ設定ができない
上記のパラメータ設定を抽象クラスにして、それの具象クラスとして下記のような実装をしていました
class BookApiService @Inject constructor(){ fun <S> create(serviceClass: Class<S>): S{ val gson = GsonBuilder() .create() val retrofit = Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create(gson)) .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) .baseUrl("https://api.openbd.jp/") .client(httpBuilder.build()) .build() return retrofit.create(serviceClass) } private val httpBuilder: OkHttpClient.Builder get() = OkHttpClient.Builder() .readTimeout(30, TimeUnit.SECONDS) }
この場合、baseurlだけが違う似たようなクラスを何個も作らないといけなくなり、あまりかっこよくないな~と思って調べたところ、@Urlオプションを見つけました こんな感じで使えます
@GET fun searchBook( @Url url: String ): Single<JsonArray>
そして呼び出し時に引数としてurlを入れておくとbaseurlを上書きしてくれるようです
これしか勝たん、と思って下記のように使ったら怒られました
@GET("v1/get") fun searchBook( @Url url: String, @Query("isbn") isbn: String ): Single<JsonArray>
GETパラメータと@Urlは併用できないというエラーが出ます ちなみにPOSTでも同じです
エラーはこんな感じ
@Url cannot be used with @GET URL (parameter #1)
baseurlは「/(スラッシュ」)」で終わらないといけない
もうオチが見えた方もいらっしゃるかと思いますが、次にこうしてみました
class BookApiService @Inject constructor(){ fun <S> create(serviceClass: Class<S>): S{ val gson = GsonBuilder() .create() val retrofit = Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create(gson)) .addCallAdapterFactory(RxJava3CallAdapterFactory.create()) .baseUrl("https://api.openbd.jp/v1/get") .client(httpBuilder.build()) .build() return retrofit.create(serviceClass) } private val httpBuilder: OkHttpClient.Builder get() = OkHttpClient.Builder() .readTimeout(30, TimeUnit.SECONDS) }
@GET fun searchBook( @Url url: String, @Query("isbn") isbn: String ): Single<JsonArray>
こうすると次は、ベースURLは/(スラッシュ)で終わらないとだめと怒られてしまいました エラーは下記の感じです
baseUrl must end in /
結局あきらめて具象クラスを複数作りましたとさ
いい解決策お持ちの方教えて下さいm( )m
まとめ
まだretorofit絶賛実装中なので随時更新していこうかなと思います
個人的にretrofitの英語はかなり易しいので好感が持てます エラーのときはイラっとするけど