In Spring Boot applications, every controller can have its own URL mapping. This makes it easy for a single application to provide web endpoints at multiple locations. For example, we can group our API endpoints into logic groupings such as internal and external.
However, there may be times where we want all of our endpoints under a common prefix. In this tutorial, we’ll look at different ways to use a common prefix for all Spring Boot controllers.
2. Servlet Context
The main component responsible for handling web requests in Spring applications is the DispatcherServlet . By customizing this component, we have a fair amount of control over how requests are routed.
Let’s take a look at two different ways to customize the DispatcherServlet that will make all of our application endpoints available at a common URL prefix.
2.1. Spring Bean
The first way is by introducing a new Spring bean:
Here, we’re creating a
ServletRegistrationBean that wraps the DispatcherServlet bean. Notice that we provide an explicit base URL of
/api/ . This means all of our endpoints must be accessed at that base URL prefix .
2.2. Application Properties
We can also achieve the same result just by using application properties. In versions of Spring Boot after 2.0.0, we would add the following to our
Prior to that version, the property name is slightly different:
One benefit of this approach is that it only uses normal Spring properties. This means we can easily change or override our common prefix using standard mechanisms like profiles or external property bindings .
2.3. Pros and Cons
The main benefit of these two approaches is also the main downside: They affect every endpoint in the application.
For some applications, this may be perfectly fine. However, some applications may need to use standard endpoint mappings to interact with third-party services - for example, OAuth exchanges. In these cases, a global solution like this may not be a good fit.
Another way we can add a prefix to all of the controllers in a Spring application is using annotations. Below, we’ll look at two different approaches.
The first way involves using Spring Expression Language (SpEL) with the standard
@RequestMapping annotation . With this approach, we simply add a property to each controller that we want to prefix:
Then, we simply specify the property value in our
3.2. Custom Annotation
Another way to achieve this is by creating our own annotation:
Then, we only need to apply the annotation to each controller we want to prefix:
3.3. Pros and Cons
These two approaches address the main concern of the previous method: They both offer fine-grained control over which controllers get the prefix . We can apply the annotations to specific controllers only, rather than impacting all endpoints in the application.
4. Server-Side Forward
One final way we will look at is using a server-side forward. Unlike a redirect, a forward does not involve a response back to the client . This means our application can pass requests between endpoints without affecting the client.
To get started, let’s write a simple controller with two endpoints:
Next, we create a new controller that is based on the prefix we want:
This controller has a single endpoint that acts as a router. In this case, it essentially flips a coin to forward the original request to one of our other two endpoints.
We can verify it’s working by sending a few consecutive requests:
The main benefit of this approach is that it is very powerful. We can apply any logic we want to determine how to forward a request: URL path, HTTP method, HTTP headers, and so on.
In this article, we’ve learned several ways to apply a common prefix to every controller in a Spring application. As with most decisions, each approach comes with pros and cons that should be carefully considered before implementation.
As always, the code examples in this tutorial can be found over on GitHub.