Introduction to Spring Boot: Building Your First RESTful API

Learn how to build your first RESTful API using Spring Boot

Building a RESTful API is a fundamental skill for any backend engineer. Spring Boot simplifies the process with its robust framework, allowing you to quickly develop scalable and maintainable APIs. In this guide, we’ll walk through creating your first RESTful API using Spring Boot. We’ll cover REST fundamentals, explain the Controller → Service → Repository pattern, mock the Repository layer, and discuss the role of Spring Security (while leaving the deeper details to specialized blog posts). By the end, you’ll have a functioning API and a deeper understanding of Spring Boot’s architecture.

What is REST? An Overview

REST (Representational State Transfer) is an architectural style used for designing networked applications. It revolves around a client-server model where the server provides resources and the client consumes them.

Main HTTP Methods:

  • GET: Retrieve data from the server.
  • POST: Send data to the server for creation.
  • PUT: Update existing data.
  • DELETE: Remove data.

Common HTTP Status Responses:

  • 200 OK: The request was successful.
  • 201 Created: The request was successful, and a resource was created.
  • 400 Bad Request: The request was malformed or invalid.
  • 401 Unauthorized: Authentication is required or failed.
  • 404 Not Found: The resource could not be found.
  • 500 Internal Server Error: The server encountered an error.

Now that we understand the basics of REST and HTTP methods, let’s dive into how to structure a Spring Boot RESTful API.

Understanding the Controller → Service → Repository Pattern

A clean architecture in Spring Boot often follows a three-layered pattern:

  1. Controller: Handles HTTP requests and responses. It acts as an interface between the user and the application logic.
  2. Service: Contains the business logic of the application. The controller delegates business tasks to the service layer.
  3. Repository: Interacts with the database. It handles CRUD (Create, Read, Update, Delete) operations and abstracts data access logic.

In this post, we’ll mock the repository layer, which means we won’t dive into actual database integration. If you’d like a deeper look at the Repository layer and how to connect Spring Boot to a real database, check out ,y guide on Spring Data JPA.

Building Your First RESTful API

Let’s start by creating a simple API that manages “users” with basic CRUD operations.

Step 1: Setting up Spring Boot

  1. Create a new Spring Boot project using Spring Initializr (https://start.spring.io).
  2. Add the following dependencies:
  • Spring Web
  • Lombok (optional but useful)
  • Spring Boot DevTools (for hot reloading)

Step 2: Create a User Entity

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Long id;
    private String name;
    private String email;
}

Step 3: Create the Controller

@RestController
@RequestMapping("/api/users")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping
    public List<User> getAllUsers() {
        return userService.getAllUsers();
    }

    @PostMapping
    public User createUser(@RequestBody User user) {
        return userService.createUser(user);
    }

    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        return userService.getUserById(id)
            .map(ResponseEntity::ok)
            .orElse(ResponseEntity.status(HttpStatus.NOT_FOUND).build());
    }

    @PutMapping("/{id}")
    public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User user) {
        return userService.updateUser(id, user)
            .map(ResponseEntity::ok)
            .orElse(ResponseEntity.status(HttpStatus.NOT_FOUND).build());
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
        if (userService.deleteUser(id)) {
            return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
        } else {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
        }
    }
}

Step 4: Create the Service Layer

@Service
public class UserService {

    private List<User> users = new ArrayList<>();

    public List<User> getAllUsers() {
        return users;
    }

    public User createUser(User user) {
        users.add(user);
        return user;
    }

    public Optional<User> getUserById(Long id) {
        return users.stream().filter(user -> user.getId().equals(id)).findFirst();
    }

    public Optional<User> updateUser(Long id, User updatedUser) {
        return getUserById(id).map(existingUser -> {
            existingUser.setName(updatedUser.getName());
            existingUser.setEmail(updatedUser.getEmail());
            return existingUser;
        });
    }

    public boolean deleteUser(Long id) {
        return users.removeIf(user -> user.getId().equals(id));
    }
}

Mocking the Repository Layer

For simplicity, we’ve mocked the Repository layer by storing data in memory using a List<User> in the UserService class. If you want to see how to connect this layer to a real database, check out my guide on Spring Data JPA.

Securing Your API

While security isn’t the focus of this post, securing APIs is crucial for protecting sensitive data. Spring Security provides a comprehensive security solution for your APIs. To learn more about how to secure your Spring Boot API, refer to my guide on Spring Security.

Conclusion

In this post, we’ve built a simple RESTful API using Spring Boot and followed a clean architecture with a Controller → Service → Repository pattern. We also briefly discussed the importance of securing your API and working with a real database. If you’re ready to dive deeper into these topics, make sure to check out the linked guides on Spring Data JPA and Spring Security.