Convert the GitHub User API Response to Java POJOs

Walk through generating Java POJOs for the GET /users/{username} response from the GitHub REST API, including snake_case fields and nested objects.

Real-world

Detailed Explanation

GitHub /users/{username} → Java

The GitHub REST API is a textbook example of a public JSON API. Its responses use snake_case keys, nest related objects (plan, organization), and include both nullable and required fields.

Sample Payload (abridged)

{
  "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"
}

Generated POJO with Jackson Annotations

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;
    // accessors
}

Refining the Generated Code

Three improvements you should consider after generation:

  1. Convert created_at / updated_at to Instant. GitHub returns ISO-8601 timestamps. With jackson-datatype-jsr310 registered, change the type to Instant (or OffsetDateTime) for proper date arithmetic.
  2. Mark optional fields as nullable with Optional getters. Fields like name, company, blog, location, and email can be null for users who have not filled out their profile.
  3. Add @JsonNaming(SnakeCaseStrategy.class) at the class level if your project standardizes on snake_case mapping. This removes most @JsonProperty annotations.

Calling the API with WebClient (Spring)

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();

Use Case

Building a GitHub integration — repository statistics dashboard, contributor leaderboard, automated onboarding bot — starts with strongly-typed access to the REST API. Generated POJOs eliminate stringly-typed Map<String, Object> parsing.

Try It — JSON to Java

Open full tool