java 84 lines · 3 tabs

Declarative Typed HTTP Client With Retrofit and an OkHttp Auth Interceptor

Shared by codesnips Aug 2026
3 tabs
package com.example.github;

import java.util.List;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Path;
import retrofit2.http.Query;

public interface GitHubApi {

    @GET("user")
    Call<User> getAuthenticatedUser();

    @GET("users/{user}/repos")
    Call<List<Repository>> getRepositories(
            @Path("user") String username,
            @Query("sort") String sort);
}
3 files · java Explain with highlit

This snippet shows the standard way to build a typed, declarative HTTP client on the JVM using Retrofit for the interface and OkHttp for the transport layer. The idea behind a declarative client is that endpoints are described as annotated Java method signatures rather than hand-written request-building code. Retrofit generates the actual implementation at runtime, converting each method call into an HTTP request and each response body into a typed model via a converter such as Gson.

In GitHubApi, the interface declares two endpoints. @GET("user") maps to a fixed path, while getRepositories uses @Path to substitute a value into users/{user}/repos and @Query to append sort as a query parameter. The return type Call<List<Repository>> is what makes the client typed: the compiler knows the exact shape of the response, and Retrofit handles deserialization. Because the method signature is the contract, this eliminates an entire class of string-concatenation and parsing bugs.

AuthInterceptor implements OkHttp's Interceptor interface, the correct place for cross-cutting request concerns. Interceptors form a chain, and this one rewrites every outgoing request via chain.request().newBuilder() to attach an Authorization header and a JSON Accept header. Requests in OkHttp are immutable, so the pattern is always to derive a new request with newBuilder() rather than mutate. The token is supplied lazily through a Supplier<String>, which decouples the interceptor from token storage and allows the credential to change over time — important once refresh logic is added. A guard skips the header when the token is blank so unauthenticated calls still work.

GitHubClientFactory wires everything together. It builds an OkHttpClient with the interceptor plus a HttpLoggingInterceptor set to BASIC, then hands that client to Retrofit.Builder. Ordering matters: the auth interceptor is added before logging so the log reflects the final request. The GsonConverterFactory connects JSON deserialization to the typed return values. Retrofit's create produces the concrete GitHubApi proxy.

A key trade-off is that Call is synchronous-or-async but not reactive; teams wanting coroutines or CompletableFuture swap the return type and adapter. Interceptors also run on every request, so expensive work there affects all traffic — token refresh in particular should be handled with an Authenticator for 401s rather than blocking inside the interceptor.


Related snips

Share this code

Here's the card — post it anywhere.

Declarative Typed HTTP Client With Retrofit and an OkHttp Auth Interceptor — share card
Link copied