Java tutorials > Frameworks and Libraries > Specific Frameworks (Spring, Hibernate) > How to create RESTful APIs using Spring Boot?
How to create RESTful APIs using Spring Boot?
This tutorial demonstrates how to create RESTful APIs using Spring Boot. We'll cover the essential annotations, project setup, and best practices for building robust and maintainable APIs.
Project Setup with Spring Initializr
The easiest way to start a Spring Boot project is using Spring Initializr (start.spring.io). Follow these steps:
Creating a Simple REST Controller
Here's a basic REST controller example:
@Controller
and @ResponseBody
, meaning methods in this class will return data directly in the response body.hello()
method.helloName()
method.
package com.example.restapi.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "Hello, World!";
}
@GetMapping("/hello/{name}")
public String helloName(@PathVariable String name) {
return "Hello, " + name + "!";
}
}
Running the Application
To run the Spring Boot application, simply execute the main method in the class generated by Spring Initializr (usually located in Once the application is running, you can access the endpoints:src/main/java/com/example/restapi/RestApiApplication.java
or a similar path). Alternatively, use your IDE's run configuration or the command line (./mvnw spring-boot:run
for Maven, ./gradlew bootRun
for Gradle).
http://localhost:8080/hello
(returns "Hello, World!")http://localhost:8080/hello/YourName
(returns "Hello, YourName!")
Creating a Resource Representation (Data Model)
A resource representation defines the structure of the data your API will expose. For example, a This simple class defines the attributes of a product. We use it to represent data transferred via our REST API.Product
class:
package com.example.restapi.model;
public class Product {
private Long id;
private String name;
private String description;
private double price;
// Constructors, Getters, and Setters (using Lombok for brevity)
public Product() {}
public Product(Long id, String name, String description, double price) {
this.id = id;
this.name = name;
this.description = description;
this.price = price;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
Creating a REST Controller with CRUD Operations
This controller demonstrates CRUD (Create, Read, Update, Delete) operations for the Important: This example uses an in-memory list to store products. In a real-world application, you would typically use a database.Product
resource:
Product
objects.Product
object or a 404 Not Found if the product doesn't exist. Uses ResponseEntity
to provide more control over the HTTP response (status code, headers, etc.).Product
object in the request body (using @RequestBody
) and returns the created product with a 201 Created status code.Product
object in the request body. Returns the updated product or a 404 Not Found.
package com.example.restapi.controller;
import com.example.restapi.model.Product;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
@RestController
@RequestMapping("/products")
public class ProductController {
private List<Product> products = new ArrayList<>();
@GetMapping
public List<Product> getAllProducts() {
return products;
}
@GetMapping("/{id}")
public ResponseEntity<Product> getProductById(@PathVariable Long id) {
Optional<Product> product = products.stream().filter(p -> p.getId().equals(id)).findFirst();
if(product.isPresent()){
return new ResponseEntity<>(product.get(), HttpStatus.OK);
}
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
@PostMapping
public ResponseEntity<Product> createProduct(@RequestBody Product product) {
product.setId((long) (products.size() + 1));
products.add(product);
return new ResponseEntity<>(product, HttpStatus.CREATED);
}
@PutMapping("/{id}")
public ResponseEntity<Product> updateProduct(@PathVariable Long id, @RequestBody Product updatedProduct) {
List<Product> collect = products.stream().filter(product -> !product.getId().equals(id)).collect(Collectors.toList());
Optional<Product> productToUpdate = products.stream().filter(p -> p.getId().equals(id)).findFirst();
if(productToUpdate.isPresent()){
Product product = productToUpdate.get();
product.setName(updatedProduct.getName());
product.setDescription(updatedProduct.getDescription());
product.setPrice(updatedProduct.getPrice());
collect.add(product);
products = collect;
return new ResponseEntity<>(product, HttpStatus.OK);
}
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
@DeleteMapping("/{id}")
public ResponseEntity<HttpStatus> deleteProduct(@PathVariable Long id) {
Optional<Product> productToDelete = products.stream().filter(p -> p.getId().equals(id)).findFirst();
if(productToDelete.isPresent()){
products.remove(productToDelete.get());
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}
Concepts Behind the Snippet
This snippet illustrates fundamental RESTful API concepts:
Real-Life Use Case Section
Imagine building an e-commerce application. You would need APIs for: Each of these would be a RESTful API with its own set of resources and endpoints.
Best Practices
/products
, not /getProducts
)./v1/products
) to avoid breaking changes for existing clients.
Interview Tip
When discussing RESTful APIs in an interview, be prepared to explain the principles of REST, the different HTTP methods, and how you would handle error handling, security, and versioning. Also, be ready to discuss your experience with different REST frameworks like Spring Boot.
When to use them
RESTful APIs are suitable when you need:
Alternatives
Alternatives to RESTful APIs include:
Pros
Cons
FAQ
-
What is the difference between @Controller and @RestController?
@Controller
is a generic annotation for marking a class as a web controller. It typically returns the name of a view to be rendered by a view resolver.@RestController
is a specialization of@Controller
that combines@Controller
and@ResponseBody
. Methods in a@RestController
directly return data in the response body (usually JSON or XML). -
What is the purpose of the @RequestBody annotation?
The
@RequestBody
annotation is used to bind the body of the HTTP request to a method parameter. It's typically used with POST and PUT requests to receive data from the client. -
How do you handle errors in a Spring Boot REST API?
You can handle errors in a Spring Boot REST API using a combination of exception handlers and
ResponseEntity
. You can create a global exception handler using@ControllerAdvice
and@ExceptionHandler
to handle specific exceptions and return appropriate error responses. -
How do you implement pagination in a Spring Boot REST API?
You can implement pagination by using Pageable object as a parameter. Here an example:
@GetMapping
public Page<Product> getAllProducts(Pageable pageable) {
return repository.findAll(pageable);
}