GitHub User API レスポンスを Java POJO に変換する

GitHub REST API の GET /users/{username} レスポンスから Java POJO を生成するウォークスルーです。snake_case フィールドとネストオブジェクトを扱います。

Real-world

詳細な説明

GitHub /users/{username} → Java

GitHub REST API は公開 JSON API の教科書的な例です。レスポンスは snake_case を使い、関連オブジェクト(plan、organization)をネストし、必須/nullable のフィールドが混在します。

サンプルペイロード(抜粋)

{
  "login": "octocat",
  "id": 583231,
  "node_id": "MDQ6VXNlcjU4MzIzMQ==",
  "avatar_url": "https://github.com/images/error/octocat_happy.gif",
  "html_url": "https://github.com/octocat",
  "type": "User",
  "site_admin": false,
  "name": "monalisa octocat",
  "company": "GitHub",
  "blog": "https://github.com/blog",
  "location": "San Francisco",
  "email": "octocat@github.com",
  "public_repos": 2,
  "public_gists": 1,
  "followers": 20,
  "following": 0,
  "created_at": "2008-01-14T04:33:35Z",
  "updated_at": "2008-01-14T04:33:35Z"
}

生成される Jackson 対応 POJO

package com.example.github;

import com.fasterxml.jackson.annotation.JsonProperty;

public class GitHubUser {
    private String login;
    private Integer id;

    @JsonProperty("node_id")
    private String nodeId;

    @JsonProperty("avatar_url")
    private String avatarUrl;

    @JsonProperty("html_url")
    private String htmlUrl;

    private String type;

    @JsonProperty("site_admin")
    private Boolean siteAdmin;

    private String name;
    private String company;
    private String blog;
    private String location;
    private String email;

    @JsonProperty("public_repos")
    private Integer publicRepos;

    @JsonProperty("public_gists")
    private Integer publicGists;

    private Integer followers;
    private Integer following;

    @JsonProperty("created_at")
    private String createdAt;

    @JsonProperty("updated_at")
    private String updatedAt;
    // アクセサ
}

生成後に検討する 3 つの改善

  1. created_at / updated_atInstant に変換する。 GitHub は ISO-8601 タイムスタンプを返します。jackson-datatype-jsr310 を登録し、型を Instant(もしくは OffsetDateTime)に変えると日付計算が安全になります。
  2. 任意フィールドを Optional getter で明示する。 namecompanybloglocationemail はプロフィール未記入のユーザーで null になります。
  3. クラスレベルで @JsonNaming(SnakeCaseStrategy.class) を付与する。 プロジェクトが snake_case マッピングで統一されているなら、ほとんどの @JsonProperty を取り除けます。

Spring の WebClient で呼び出す

WebClient client = WebClient.create("https://api.github.com");
GitHubUser user = client.get()
    .uri("/users/octocat")
    .header("Accept", "application/vnd.github+json")
    .retrieve()
    .bodyToMono(GitHubUser.class)
    .block();

ユースケース

リポジトリ統計ダッシュボード、コントリビュータランキング、自動オンボーディング bot など、GitHub 連携は強く型付けされた REST API アクセスから始まります。生成 POJO により Map<String, Object> ベースの文字列頼り処理を排除できます。

試してみる — JSON to Java

フルツールを開く