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:
- Convert
created_at/updated_attoInstant. GitHub returns ISO-8601 timestamps. Withjackson-datatype-jsr310registered, change the type toInstant(orOffsetDateTime) for proper date arithmetic. - Mark optional fields as nullable with Optional getters. Fields like
name,company,blog,location, andemailcan be null for users who have not filled out their profile. - Add
@JsonNaming(SnakeCaseStrategy.class)at the class level if your project standardizes on snake_case mapping. This removes most@JsonPropertyannotations.
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.