Spring Boot
controllers
URL prefix
Java
web development

How to specify prefix for all controllers in Spring Boot?

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

In Spring Boot applications, managing request mappings effectively is crucial for maintaining clear and organized routes. Prefixing all controllers with a specific path is a common requirement for better versioning and grouping of endpoints. This article explores various methods to set a prefix for all controller routes in a Spring Boot application, delving into technical explanations and examples for effective implementation.

Understanding Spring MVC and Spring Boot

Spring Boot builds on Spring's popular web framework, Spring MVC, to provide an easy-to-integrate web development environment. Controllers in a Spring MVC application handle incoming HTTP requests and provide responses. Typically, you define a controller by annotating a class with @RestController or @Controller, combined with @RequestMapping annotations to specify request paths.

Problem Statement

When developing a Spring Boot application, you might need to add a common prefix to all controller routes. This is useful for versioning (e.g., /api/v1/...) or similar purposes. Implementing this consistently can simplify the configuration and maintenance of routing logic across your application.

Methods to Set a Prefix for All Controllers

1. Using @RequestMapping at Class Level

A straightforward way to set a prefix is to use the @RequestMapping annotation at the class level in each controller. This approach involves directly specifying the prefix when defining each controller.

java
1@RestController
2@RequestMapping("/api/v1")
3public class MyController {
4    @GetMapping("/items")
5    public List<String> getItems() {
6        return List.of("Item1", "Item2");
7    }
8}

Pros:

  • Simple and explicit
  • Easy to understand for each controller

Cons:

  • Repetitive across multiple controllers
  • Violates the DRY (Don't Repeat Yourself) principle

2. Utilizing a RequestHandler Interceptor

A more elegant solution is to define an interceptor that automatically appends the prefix to each request. Spring's HandlerInterceptorAdapter can be customized to alter request paths before they reach their respective controllers.

java
1@Configuration
2public class WebMvcConfig implements WebMvcConfigurer {
3    @Override
4    public void addInterceptors(InterceptorRegistry registry) {
5        registry.addInterceptor(new HandlerInterceptorAdapter() {
6            @Override
7            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
8                if (handler instanceof HandlerMethod) {
9                    HandlerMethod handlerMethod = (HandlerMethod) handler;
10                    RequestMapping requestMapping = handlerMethod.getMethodAnnotation(RequestMapping.class);
11                    if (requestMapping != null) {
12                        // Modify request path here if needed
13                    }
14                }
15                return true;
16            }
17        });
18    }
19}

Pros:

  • Centralized configuration
  • Reduces redundancy in each controller

Cons:

  • Potential complexity in managing interceptor logic
  • Requires careful handling to avoid unexpected route changes

3. Utilizing Properties and Path Patterns

Spring Boot allows externalizing configuration through properties. You can define a prefix in application.properties and reference it in controllers using path variables or directly apply it in the configuration.

properties
api.prefix=/api/v1
java
1@RestController
2@RequestMapping("${api.prefix}/items")
3public class MyController {
4    @GetMapping
5    public List<String> getItems() {
6        return List.of("Item1", "Item2");
7    }
8}

Pros:

  • Separates configuration from code
  • Easy to change the prefix without code modifications

Cons:

  • Can become cumbersome for complex configurations
  • Requires careful attention to externalized property management

4. Using Global Request Mapping with Custom Configuration Class

You can define a custom component that programmatically configures all controllers with a global prefix. This requires a deeper understanding of Spring Boot's capabilities but can provide a clean solution.

java
1@Configuration
2public class RequestMappingConfig implements WebMvcRegistrations {
3    @Override
4    public RequestMappingHandlerMapping getRequestMappingHandlerMapping() {
5        return new RequestMappingHandlerMapping() {
6            @Override
7            protected void registerHandlerMethod(Object handler, Method method, RequestMappingInfo mapping) {
8                RequestMappingInfo finalMapping = RequestMappingInfo.paths("/api/v1")
9                                                .build()
10                                                .combine(mapping);
11                super.registerHandlerMethod(handler, method, finalMapping);
12            }
13        };
14    }
15}

Pros:

  • Programmatic control over request patterns
  • Offers a clean, uniform configuration

Cons:

  • Increased complexity in understanding and maintaining the configuration
  • Requires familiarity with Spring's internals

Summary Table

MethodProsCons
@RequestMapping at Class LevelSimple and explicit Easy to understandRepetitive across controllers Violates DRY
RequestHandler InterceptorCentralized configuration Reduces redundancyComplexity in logic Risk of unintended routes
Properties and Path PatternsConfiguration separate from code Easy updatesCumbersome for complex configs Carefully managed
Global Request Mapping with Custom ClassProgrammatic, clean configuration UniformityComplex to maintain Requires Spring expertise

Conclusion

Adding a prefix to all controllers in a Spring Boot application enhances organization, facilitates API versioning, and aligns URL structures. Several approaches are available, each with unique advantages and implications. Choosing the right method depends on the application's complexity and the development team's familiarity with Spring Boot's capabilities. Understanding these options ensures better management of request mappings and contributes to the overall effectiveness of your Spring Boot applications.


Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.