7 Ways to Add a Unified Prefix to Spring Boot Controllers
This article explains why a common API prefix (e.g., /api/v1) is useful in microservice or front‑back separation projects and demonstrates seven practical techniques—custom DispatcherServlet registration, YAML configuration, SpEL‑based @RequestMapping, custom composed annotation, WebMvcConfigurer addPathPrefix, internal forwarding, Spring Cloud Gateway ProxyExchange, and Nginx reverse proxy—using Spring Boot 3.5.0 examples and code snippets.
1. Introduction
In microservice architectures or front‑back separated projects, adding a uniform prefix such as /api/v1 to controller endpoints is a standard best practice. It supports API versioning, simplifies gateway routing and security configuration, and separates dynamic API paths from static front‑end resources.
2. Implementation Examples (Spring Boot 3.5.0)
2.1 Custom DispatcherServlet Registration
@Configuration
public class ServletConfig {
@Bean
public DispatcherServletRegistrationBean dispatcherServletRegistration(
DispatcherServlet dispatcherServlet,
WebMvcProperties webMvcProperties,
ObjectProvider<MultipartConfigElement> multipartConfig) {
DispatcherServletRegistrationBean registration =
new DispatcherServletRegistrationBean(dispatcherServlet, "/api/");
registration.setName("dispatcherServlet");
registration.setLoadOnStartup(webMvcProperties.getServlet().getLoadOnStartup());
multipartConfig.ifAvailable(registration::setMultipartConfig);
return registration;
}
}All controller mappings will now be accessed under the /api/** prefix.
2.2 Configuration File
spring:
mvc:
servlet:
path: /apiSetting the servlet path in application.yml automatically prefixes every request.
2.3 SpEL‑Based @RequestMapping
Define a property and use Spring Expression Language in the mapping:
@RestController
@RequestMapping(path = "${pack.app.apiPrefix}/users")
public class UserController {
// ...
} pack:
app:
api-prefix: /apiThis approach requires modifying each controller but keeps the prefix configurable.
2.4 Custom Composed Annotation
@RequestMapping(value = "/api/")
public @interface PackMapping {}
// Usage
@RestController
@PackMapping
public class UserController {
@RequestMapping("/users")
public String getAll() {
return "...";
}
}A custom annotation abstracts the prefix, making it reusable and concise.
2.5 WebMvcConfigurer addPathPrefix
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.addPathPrefix("/api", clazz -> true);
}
}The addPathPrefix method adds the prefix to all controller classes; the predicate can be refined for selective application.
2.6 Internal Forwarding (Custom Routing)
@RestController
public class EndpointController {
@GetMapping("/endpoint1")
public String endpoint1() { return "..."; }
@GetMapping("/endpoint2")
public String endpoint2() { return "..."; }
}
@Controller
@RequestMapping("/api/endpoint")
public class ApiPrefixController {
@GetMapping
public ModelAndView route(ModelMap model, HttpServletRequest request) {
String action = request.getHeader("X-ACTION");
return switch (action) {
case null -> new ModelAndView("forward:/error");
case "xxx" -> new ModelAndView("forward:/endpoint1", model);
case "zzz" -> new ModelAndView("forward:/endpoint2", model);
default -> new ModelAndView("forward:/home");
};
}
}This method forwards requests server‑side without involving the client, preserving the original request flow.
2.7 Spring Cloud Gateway ProxyExchange
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-gateway-proxyexchange-webmvc</artifactId>
<version>4.3.5</version>
</dependency> @RestController
public class GatewayController {
@GetMapping("/api/{*path}")
public Object proxy(ProxyExchange<Object> proxy, HttpServletRequest request) throws Exception {
String targetURI = proxy.path("/api");
URI uri = ServletUriComponentsBuilder.fromServletMapping(request)
.path(targetURI)
.build()
.toUri();
return proxy.uri(uri).get();
}
}The example handles GET requests; POST and other methods can be added similarly.
2.8 Nginx Reverse Proxy
server {
listen 80;
server_name default;
location /api/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
rewrite ^/api/(.*)$ /$1 break;
proxy_pass http://www.pack.com;
}
}This configuration forwards all /api/** requests to the backend without modifying application code.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
