
Building Your First REST API with Spring Boot
A hands-on guide to building your first REST endpoints in Spring Boot using @RestController and @GetMapping, and returning JSON from your API.
August 17, 2026 · 5 min read
In the last chapter, we saw how logging works in Spring Boot. Now let's put everything we've built so far to use and create our first REST API.
What Is a REST API?
A REST API lets other applications talk to your Spring Boot app over HTTP — a client sends a request to a URL, and your app sends back data, usually as JSON. It's the standard way a frontend, a mobile app, or another service talks to a backend like the one we're building.
Remember the Whitelabel Error Page we hit back in Chapter 3 when we opened http://localhost:8080? That happened because there was no endpoint to handle the request. Let's fix that now.
The @RestController and @GetMapping
Back in Chapter 6, we previewed two annotations we'd need for this: @RestController and @GetMapping. Here's what they actually do.
@RestController marks a class as a REST endpoint handler. It's a specialization of @Component (so it gets picked up by component scanning, same as any other bean we've built so far), combined with an instruction that tells Spring to write every method's return value straight into the HTTP response body, instead of resolving it to an HTML view.
@GetMapping("/path") maps HTTP GET requests for that path to the method it's placed on.
Your First REST Endpoint
Add this HelloController class to your project, right alongside HelloSpringApplication:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
public String sayHello() {
return "Hello, Spring Boot!";
}
}Run the app (./gradlew bootRun) and open http://localhost:8080/hello in your browser. Instead of the Whitelabel Error Page, you'll see:
Hello, Spring Boot!That's your first REST endpoint.
Returning JSON
A plain String response like the one above is sent back as text/plain, not JSON — fine for a quick test, but not what most real APIs return. To return JSON, just return any Java object other than a String — a Map, a List, a record, a class with getters. Spring Boot uses a library called Jackson (already on your classpath thanks to spring-boot-starter-web) to serialize it automatically.
Let's put this to use with the WeatherService we built back in Chapter 7. Instead of printing its forecast to the console, let's expose it over HTTP:
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@RestController
@RequestMapping("/weather")
public class WeatherController {
private final WeatherService weatherService;
public WeatherController(WeatherService weatherService) {
this.weatherService = weatherService;
}
@GetMapping
public Map<String, String> getForecast() {
return Map.of(
"city", "New York",
"forecast", "Sunny",
"temperature", "25°F"
);
}
}A couple of things worth calling out:
@RequestMapping("/weather")on the class sets a base path for every endpoint in this controller.@GetMappingwith no path on the method maps to that base path itself — so this method handlesGET /weather.- We're injecting
WeatherServicethrough the constructor, exactly the way Chapter 5 told you to — nonew WeatherService()anywhere in sight.
Run the app and open http://localhost:8080/weather. You'll see real JSON this time:
{"city":"New York","forecast":"Sunny","temperature":"25°F"}Testing Your Endpoint
A browser works fine for GET requests, but it won't show you response headers. For that, use curl:
curl -i http://localhost:8080/weatherThe -i flag prints the response headers along with the body — look for Content-Type: application/json, which is Spring Boot confirming it serialized your response as JSON. Later in the course, in Chapter 22, we'll set up Swagger, which gives you a UI for testing endpoints like this without typing out curl commands by hand.
A Note on Status Codes
Notice we didn't have to set anything to get a 200 OK back — Spring Boot returns that by default whenever a controller method completes without throwing an exception. We'll get into customizing status codes and handling errors properly starting in Chapter 19, Centralized Error Handling.
Summary
In this chapter, we built our first two REST endpoints using @RestController and @GetMapping, saw the difference between a plain-text response and a real JSON one, and wired an existing service into a controller using the constructor injection pattern from Chapter 5.
Right now, both of our endpoints return fixed, hardcoded data. In the next chapter, we'll fix that: Handling Request Parameters, Path Variables, and Request Bodies covers how to accept input from the client so your endpoints can actually respond to what's being asked.
