SORACOM APIをRetrofit-2.0.0beta2で書く作業をしていたときにはまったポイントを記載します。Retrofit-1.x代とはコンセプトが違う部分なのでv2.0.0に移行するときは気をつけたほうがいいところでもあります。
☆今回はRetrofitとは何か、というのは説明しません。知りたい方は
http://square.github.io/retrofit/
やQiita内で投稿されているドキュメントなどをみてください。
今回私がはまったソース
私が最初Retrofit2.0.0-beta2を使って書いたSORACOM APIのクラスがこちらです。
public final class Soracom {
public static final Api API;
static {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.soracom.io/v1" )
.addConverterFactory(GsonConverterFactory.create())
.build();
API = retrofit.create(Api.class);
}
private Soracom() {
}
public interface Api {
@POST("/auth" )
Call<AuthInfo> auth(@Body AuthRequest authRequest);
}
}
一見正しそうに見えますが、ダメでした。(ステータスコード500でかえってきます。)
ダメな理由
上記のコードがダメな理由はRetrofit.Builder#baseUrl
と@POST(@GET)
でつくられるURLのルールに沿って作られていなかったからです。
実は、上記コードではhttps://api.soracom.io/auth
にアクセスしてしまいます。(https://api.soracom.io/v1/auth
にアクセスするのが正しい。)
Retrofit2.0.0-beta2の仕様で
・Retrofit.Builder#baseUrl
に指定したURLの後ろに「/」が付いていない場合は強制的に「[schema]://[authority]」(上記でいうとschema=http, authrityはapi.soracom.io)という形を使ってアクセス先のURLを構築する。
・@GET
,@POST
の中に指定するURLの先頭に「/」が付いているとbaseUrl
で指定したURLの「[schema]://[authority]」のすぐ後ろにくっつけてしまう。
となっています。
(http://www.github.comをみたいな形のURLを指定すれば何も問題ないんですけどね…)
解決策
なので解決策として
・Retrofit.Builder#baseUrl
に定めるURLは必ず「/」で終わるようにする。
・@GET
,@POST
の中に指定するURLは「/」で始めないようにする。
を採択しました。
対応したコードは以下のようになります。
public final class Soracom {
public static final Api API;
static {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.soracom.io/v1/" )
.addConverterFactory(GsonConverterFactory.create())
.build();
API = retrofit.create(Api.class);
}
private Soracom() {
}
public interface Api {
@POST("auth" )
Call<AuthInfo> auth(@Body AuthRequest authRequest);
}
}
こうすると想定したURLにきちんとアクセスしてくれるので問題が解決されました。
まとめ
Retrofit2.0.0-beta2を使うときにはbaseUrl
,@GET
,@POST
に指定するURLのフォーマットには十分に気をつけましょう!!具体的には
・Retrofit.Builder#baseUrl
に定めるURLは必ず「/」で終わるようにする。
・@GET
,@POST
の中に指定するURLは「/」で始めないようにする。
をしていただければ問題ないと思います。
参考URL
http://inthecheesefactory.com/blog/retrofit-2.0/en
・このサイトの「New URL resolving concept. The same way as <a href>
」というところに同じような内容が書いてあります。