backend

4 min read

Top 10 Spring Boot REST API Best Practices (With Code Examples)

Explore the top 10 Spring Boot REST API best practices for creating clean, secure, and scalable APIs. Enhance your API development skills with practical code examples and expert tips for professional-grade Spring Boot applications.

Top 10 Spring Boot REST API Best Practices (With Code Examples) thumbnail

Published By: Nelson Djalo | Date: May 5, 2025

Top 10 Spring Boot REST API Best Practices (With Code Examples)

Spring Boot makes it easy to build REST APIs quickly, but writing clean, secure, and scalable APIs still requires following best practices. In this guide, you'll learn the top 10 Spring Boot REST API best practices that will help you write professional-grade APIs ready for production.

Whether you're building internal tools or public APIs, these tips will help you avoid common mistakes, improve maintainability, and impress your team.

🚀 1. Use Consistent and RESTful Resource Naming

Always use plural nouns and avoid action words in your URLs.

❌ Bad

@GetMapping("/getAllUsers")

✅ Good

@GetMapping("api/v1/users")

Keep endpoints clean and meaningful:

  • api/v1/users – get all users
  • api/v1/users/{id} – get user by ID
  • api/v1/users (POST) – create new user
  • api/v1/users/{id} (PUT/PATCH) – update user
  • api/v1/users/{id} (DELETE) – delete user

2. Return the Correct HTTP Status Codes

Always return status codes that reflect what happened on the server. For example use 201 Created when creating resources instead of returning 200 OK.

@PostMapping("/users")
public ResponseEntity<UserDto> createUser(@RequestBody @Valid UserRequest request) {
    UserDto created = userService.createUser(request);
    return ResponseEntity.status(HttpStatus.CREATED).body(created);
}

Common status codes:

  • 200 OK – Success
  • 201 Created – New resource created
  • 204 No Content – Successfully deleted
  • 400 Bad Request – Validation failed
  • 404 Not Found – Resource not found
  • 500 Internal Server Error – Something went wrong

3. Use DTOs Instead of Entities

Never expose your database entities directly. Use Data Transfer Objects (DTOs).

❌ Bad:

public ResponseEntity<User> getUser(@PathVariable Long id) { ... }

✅ Good:

public ResponseEntity<UserResponse> getUser(@PathVariable Long id) {
    User user = userRepository.findById(id).orElseThrow(() -> new UserNotFoundException("User not found"));
    return ResponseEntity.ok(new UserResponse(user.getId(), user.getName()));
}

Map between DTOs and entities in your service layer to protect internal data and structure.

4. Use Bean Validation for Request Bodies

Avoid manual if-checks and use Jakarta Bean Validation (@Valid, @NotBlank, etc.).

❌ Bad:

if (user.getName().isBlank()) {
    throw new IllegalArgumentException("Name is required");
}

✅ Good:

public record UserRequest(
    @NotBlank String name,
    @NotBlank String password
) {}

@PostMapping("/users")
public ResponseEntity<?> createUser(@RequestBody @Valid UserRequest request) { ... }

5. Apply Separation of Concerns

Structure your code using the Controller-Service-Repository pattern.

Controller → Service → Repository → Database

Example:

@RestController
@RequestMapping("/users")
public class UserController {
    private final UserService userService;

    @PostMapping
    public ResponseEntity<UserDto> create(@RequestBody @Valid UserRequest req) {
        return ResponseEntity.status(HttpStatus.CREATED).body(userService.createUser(req));
    }
}
@Service
public class UserService {
    private final UserRepository userRepository;

    public UserDto createUser(UserRequest req) {
        User user = new User(req.name(), req.password());
        userRepository.save(user);
        return new UserDto(user.getId(), user.getName());
    }
}

6. Implement Pagination and Limit Results

Never return thousands of records at once. Use pagination with Spring Data.

Controller Example:

@GetMapping
public Page<UserDto> getUsers(Pageable pageable) {
    return userService.getUsers(pageable);
}

Sample request:

GET /users?page=0&size=10&sort=name,asc

7. Use Global Exception Handling

Handle errors in one place using @ControllerAdvice.

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<String> handleValidation(MethodArgumentNotValidException ex) {
        return ResponseEntity.badRequest().body("Validation failed: " + ex.getMessage());
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleAll(Exception ex) {
        return ResponseEntity.status(500).body("Internal error: " + ex.getMessage());
    }
}

8. Secure Your APIs

Secure your endpoints using Spring Security:

  • Use JWT, OAuth2, or Basic Auth
  • Protect sensitive routes
  • Validate user roles/permissions

Example:

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/admin/**").hasRole("ADMIN")
                .anyRequest().authenticated()
            )
            .httpBasic();
        return http.build();
    }
}

9. Version Your API

Keep old versions alive by versioning your endpoints.

Example:

@RequestMapping("/api/v1/users")
public class UserControllerV1 { ... }

@RequestMapping("/api/v2/users")
public class UserControllerV2 { ... }

Avoid breaking changes to existing consumers.

10. Document Your API with Swagger / OpenAPI

Use SpringDoc OpenAPI or Swagger UI for interactive documentation.

Add dependency:

<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.2.0</version>
</dependency>

Access documentation at:

http://localhost:8080/swagger-ui.html

It helps frontend developers and third parties understand your API.

Conclusion

By following these best practices, you'll write cleaner, more maintainable, and secure REST APIs with Spring Boot.

  • Follow RESTful naming conventions
  • Use the right status codes
  • Protect your domain with DTOs
  • Handle validation and exceptions properly
  • Structure your code for scalability
  • Secure and document your APIs

Video Tutorial

The One-Stop Platform for Developers

Get unlimited access to coding courses, Quizzes, Builds and Tools. Start your journey or level up your career with Amigoscode today!