Building a REST API with Spring Boot
A REST API is a way for applications to talk to each other over HTTP using standard methods (GET, POST, PUT, DELETE) and resource-based URLs, typically exchanging JSON. Building one in Spring Boot is remarkably fast: you annotate a class with @RestController, map methods to URL paths, and Spring handles converting your Java objects to and from JSON automatically. By the end of this guide you will understand REST principles and have a working CRUD API.
REST in one minute
REST organises your API around resources (nouns like "courses" or "students"), each addressed by a URL, and uses HTTP methods to express the action:
GET /courses— list all coursesGET /courses/42— get one coursePOST /courses— create a coursePUT /courses/42— update a courseDELETE /courses/42— delete a course
Notice the URLs name things, not actions. The HTTP method supplies the verb. Following this convention makes your API predictable for any client.
A working REST controller
In Spring Boot, @RestController combines @Controller with @ResponseBody, meaning every method's return value is serialized straight to the response body as JSON:
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/courses") // base path for every method below
public class CourseController {
private final CourseService service;
// Constructor injection — Spring supplies the service bean
public CourseController(CourseService service) {
this.service = service;
}
// GET /api/courses -> returns a JSON array of courses
@GetMapping
public List<Course> listAll() {
return service.findAll();
}
// GET /api/courses/42 -> {id} is read from the URL path
@GetMapping("/{id}")
public ResponseEntity<Course> getOne(@PathVariable long id) {
Course course = service.findById(id);
if (course == null) {
// Return 404 when the resource does not exist
return ResponseEntity.notFound().build();
}
return ResponseEntity.ok(course); // 200 with the course as JSON
}
// POST /api/courses -> @RequestBody parses the incoming JSON into a Course
@PostMapping
public ResponseEntity<Course> create(@RequestBody Course newCourse) {
Course saved = service.create(newCourse);
// 201 Created is the correct status for a successful POST
return ResponseEntity.status(HttpStatus.CREATED).body(saved);
}
// DELETE /api/courses/42 -> 204 No Content on success
@DeleteMapping("/{id}")
public ResponseEntity<Void> delete(@PathVariable long id) {
service.delete(id);
return ResponseEntity.noContent().build();
}
}
Spring Boot uses Jackson under the hood to turn Course objects into JSON and to parse incoming JSON request bodies — you write zero serialization code.
Want to learn this properly?
Join the waitlist for our courses — beginner-friendly, project-first classes in Jalgaon.
Browse coursesUse the right status codes
A professional REST API communicates outcomes through HTTP status codes:
- 200 OK — successful GET or update.
- 201 Created — successful POST that created a resource.
- 204 No Content — successful action with nothing to return (like DELETE).
- 400 Bad Request — the client sent invalid data.
- 404 Not Found — the resource does not exist.
ResponseEntity gives you precise control over both the status and the body, as shown above.
Common mistakes
- Putting verbs in URLs like
/getCourseor/createCourse. URLs name resources; the HTTP method is the verb. Use/courseswith GET/POST. - Returning 200 for everything. A created resource should return 201, a missing one 404. Status codes are part of your API contract.
- Using
@Controllerinstead of@RestController. Without@RestController(or@ResponseBody), Spring treats your return value as a view name, not JSON. - Skipping input validation. Validate request bodies (e.g. with Jakarta Bean Validation annotations) so bad data is rejected with a clear 400.
- Exposing internal entities directly. For real apps, map entities to DTOs so internal database fields do not leak into your public API.
FAQ
Do I need a separate JSON library? No. Spring Boot's web starter includes Jackson and configures it automatically.
What is the difference between @PathVariable and @RequestParam?
@PathVariable reads a value from the URL path (/courses/42), while @RequestParam reads a query parameter (/courses?active=true).
Keep learning
A REST API needs data, so pair this with JDBC or Hibernate and JPA. It all runs on Spring Boot. Explore more in the Advanced Java hub.
Want to build production REST APIs with confidence? Join the waitlist for the Advanced Java course at Infoplanet, Jalgaon.
Want to learn this properly?
Join the waitlist for our courses — beginner-friendly, project-first classes in Jalgaon.
Browse coursesFounder, Infoplanet
Atul Kabra founded Infoplanet in 2001 and has spent over two decades teaching programming — C, C++, Java, databases and more — to students across Maharashtra.
Related guides
Advanced Java / Backend Roadmap
A clear, ordered roadmap for learning Advanced Java and backend development — from core Java through servlets, Spring Boot, REST APIs, and deployment.
Deploying a Java Web App
A practical guide to deploying a Spring Boot app: build an executable JAR, run it on a server, containerise with Docker, and check production essentials.
Hibernate & JPA Basics
Hibernate is the leading JPA implementation that maps Java objects to database tables. This guide explains ORM, entities, and the Jakarta Persistence annotations.
