ProbableOdyssey | Blake Cook

HTTP Requests in Java

· 2 min read · 317 words

After almost 10 years in Python, I’m making my way into the land of Java. There’s a heap to learn, and I learn best by doing. My first project is fairly simple — hit an API and process the returned data. Using the requests package in Python is immediately what I reach for, but Java seems to have a nicer interface out-of-the-box.

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;

HttpClient client = HttpClient.newHttpClient();

GET Request

Python:

resp = requests.get(
    url,
    headers={"Authorization": f"Bearer {token}"},
)
data = resp.json()

Java:

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create(url))
    .header("Authorization", "Bearer " + token)
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

Python does it in one call, Java splits it into build the request then send the request. The builder pattern is everywhere in Java (for better or worse, the meme of the FooFactory, FooFactoryFactory and FooFactoryFactoryFactory in Java is something to watch out for)

POST Request

Python:

resp = requests.post(
    url,
    headers={"Content-Type": "application/x-www-form-urlencoded"},
    data=body,
)

Java:

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create(url))
    .header("Content-Type", "application/x-www-form-urlencoded")
    .POST(HttpRequest.BodyPublishers.ofString(body))
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

The only new concept: BodyPublishers.ofString() wraps your string into the request body. GET is the default, so you must explicitly call .POST().

JSON Parsing

Python: response.json(). Done.

Java: no built-in JSON parsing (?), use the jackson package:

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

ObjectMapper mapper = new ObjectMapper();
JsonNode data = mapper.readTree(response.body());
String name = data.get("name").asText();

JsonNode is a generic tree - you traverse it with .get("key") and convert types with .asText(), .asInt(), etc.

The Full Pattern

Here’s what a real API client looks like - this is the pattern I used everywhere to hit the Spotify API:

public class SpotifyClient {
    private static HttpClient client = HttpClient.newHttpClient();
    private String accessToken;

    public SpotifyClient() throws IOException, InterruptedException {
        this.accessToken = getAccessToken();
    }

    private JsonNode callEndpoint(String endpoint) throws IOException, InterruptedException {
        HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(endpoint))
            .header("Authorization", "Bearer " + accessToken)
            .build();

        HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
        return new ObjectMapper().readTree(response.body());
    }
}

#builder-pattern #api #http-requests #http #json-parsing #api-client #comparison #python #java #json #jackson

Reply to this post by email blZake@proZbableodyssey.blog (remove Z characters) ↪

Comments

Leave a comment

Markdown is supported. Your email is private and only used if you'd like a reply.