前提
json:apiの仕様に基づいたjsonを返すAPIサーバを持っていること。
経緯
json:apiを返すRailsサーバとAndroidアプリを通信させる必要があった。 json:apiとember-dataはお友達、でもJavaでどうすればいいのか分からなかったから調べた。
調査結果
retrofitとjsonapi-converterを使うといい感じに通信できる。
1. google http clientを試した
httpクライアントとしてはJavaでは apacheのもの が定番のようだったがサイトがとっつきづらかったのでgoogle製のものを使ってみた。しかし、ネストしたプロパティへのマッピングができなかったので断念。
こんな感じにマッピングできます。フラットなjsonならこれで十分ですね。
2. jsonの取得とdesrializationを別に考えようとして、desrializationライブラリを探したら取得のとこもちゃんとサポートしていた
json:apiのspecページでは、さまざまな実装をまとめています (http://jsonapi.org/implementations/) 。Javaの項目を見ると、"jsonapi-converter"というライブラリを見つけました。名前からしてjsonの取得まではサポートしていなさそう・・・。 retrofitというhttpクライアントと連携できる・・・。
Retrofitの簡単な紹介とjsonapi-converterとどう連携するか
APIバックエンドサーバサービスをインターフェイスとして定義し、利用する形式のhttpクライアントです。下記のように使えます。さてサービスから返ってきたjsonのマッピングですが、これをjsonapi-converterで担います。
public interface MyAwesomeBackendService {
@get("/users")
List<User> getUsers();
}
Retrofit retrofit = new Retrofit.builder().baseUrl("http://localhost:3000").build();
MyAwesomeBackendService service = retrofit.create(MyAwesomeBackendService.class);
service.getUsers();
jsonapi-converterでマッピング
ほとんど公式docです。今回呼び出し部分は全てjsonapi-converterに書いてあるので割愛します。
ObjectMapper objectMapper = new ObjectMapper();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://localhost:3000")
.addConverterFactory(new JSONAPIConverterFactory(objectMapper, User.class))
.build();
MyAwesomeBackendService service = retrofit.create(MyAwesomeBackendService.class);
TIPS: jsonのキーの形式を指定する (snake, camel, hyphenated)
今回バックエンドAPIサーバのライブラリの都合上、jsonのキーがスネークケースになっていました(json:api推奨はhyphenated)。ObjectMappterを生成するときにオプションが渡せるのでキーの形式がどのようなものか教えてあげるといいです。
ObjectMapper objectMapper = new ObjectMapper().setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);