DEV Community

Adeshola Racheal Adetona
Adeshola Racheal Adetona

Posted on

Building a Simple RESTful API in Java

Overview

Recently, I built a lightweight RESTful API using only Java — no Spring Boot, no frameworks, just the standard Java libraries.
The goal was to create a simple /me endpoint that returns my profile information along with a dynamic cat fact fetched from an external API called Cat Facts API (https://catfact.ninja/fact).

This task validated my ability to:

  • Consume third-party APIs
  • Format JSON responses
  • Return dynamic data from a Java HTTP server
  • Handle errors and timeouts gracefully

🧩 The Task

The requirements were clear:

✅ Create a GET endpoint at /me
✅ Return JSON data with this structure:

{
"status": "success",
"user": {
"email": "get2adeshola@gmail.com",
"name": "Adeshola Adetona",
"stack": "Java"
},
"timestamp": "2025-10-18T12:34:56.789Z",
"fact": "A random cat fact"
}

Fetch a fresh random fact from Cat Facts API on every request
Handle API failure gracefully
Ensure Content-Type: application/json

Tools & Stack

Language: Java 17

Libraries: None (used com.sun.net.httpserver.HttpServer)

IDE: IntelliJ IDEA

Version Control: Git + GitHub

Testing Tool: cURL / Browser

🧱 Implementation Steps
Step 1 — Create a Simple HTTP Server

Instead of using Spring Boot, I used Java’s built-in HTTP server:

HttpServer server = HttpServer.create(new InetSocketAddress(8080), 0);
server.createContext("/me", new ProfileHandler());
server.setExecutor(null);
server.start();
System.out.println("Server started on port 8080");

This created a lightweight server that listens for requests on port 8080.

Step 2 — Define the Handler

The handler processes /me requests, fetches a random cat fact, and builds the JSON response:

public void handle(HttpExchange exchange) throws IOException {
if ("GET".equals(exchange.getRequestMethod())) {
String fact = fetchCatFact();
String response = buildResponse(fact);

    exchange.getResponseHeaders().set("Content-Type", "application/json");
    exchange.sendResponseHeaders(200, response.getBytes().length);

    OutputStream os = exchange.getResponseBody();
    os.write(response.getBytes());
    os.close();
}
Enter fullscreen mode Exit fullscreen mode

}

Step 3 — Fetching the Cat Fact

I connected to the public Cat Facts API using HttpURLConnection:

private static String fetchCatFact() {
try {
URL url = new URL("https://catfact.ninja/fact");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(3000);
conn.setReadTimeout(3000);

    BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
    String json = reader.lines().collect(Collectors.joining());
    reader.close();

    return new JSONObject(json).getString("fact");
} catch (Exception e) {
    return "Could not fetch cat fact at this time.";
}
Enter fullscreen mode Exit fullscreen mode

}

This ensures:

Each request gets a new cat fact

If the API fails, a fallback message appears instead

Step 4 — Generate the JSON Response
private static String buildResponse(String fact) {
JSONObject response = new JSONObject();
response.put("status", "success");

JSONObject user = new JSONObject();
user.put("email", "get2adeshola@gmail.com");
user.put("name", "Adeshola Adetona");
user.put("stack", "Java");

response.put("user", user);
response.put("timestamp", Instant.now().toString());
response.put("fact", fact);

return response.toString();
Enter fullscreen mode Exit fullscreen mode

}

Testing the API

I ran the server locally with:

java ProfileServer

Then tested it using:

curl http://localhost:8080/me

Output:

{
"status": "success",
"user": {
"email": "get2adeshola@gmail.com",
"name": "Adeshola Adetona",
"stack": "Java"
},
"timestamp": "2025-10-18T14:22:07.231Z",
"fact": "Cats sleep for 70% of their lives."
}

This task taught me:

How to serve APIs without frameworks
I now understand how Spring Boot simplifies low-level operations.

HTTP fundamentals : handling connections, status codes, and headers manually.

Resilience : implementing fallback responses for third-party API failures.

Clean JSON formatting and working with timestamps in ISO 8601.

Version control workflow : initializing a repo, committing, and pushing to GitHub.

IntelliJ Project Setup
IntelliJ Project Setup

Running the Server
Running the Server

Testing with browser
Testing with browser

Repository

https://github.com/Tonathe3rd/Dynamic-Profile-Endpoint-HNG

API can be found in the Railway app here: https://dynamic-profile-endpoint-hng-production.up.railway.app/me

Conclusion

Building this project from scratch reminded me that even without frameworks, Java remains powerful for web development, it just requires a little more setup.
This exercise sharpened my understanding of how HTTP servers, JSON, and APIs work under the hood.

Author

Adeshola Adetona
get2adeshola@gmail.com
Backend Stack: Java
Cat Fact Enthusiast

Top comments (0)