Adam Madoyan
Adam Madoyan

Reputation: 145

How to change base url only for rest controllers?

Is there any configuration option that allows to change base url only for rest controllers, for example if my api's base url is www.example.com/user/{id} becomes www.example.com/rest/user/{id} ?

I am using spring boot v1.3.2

I tried to create custom annotation which extends RestController by adding RequestMapping. Here is the example, but it does not work.

@Target(ElementType.TYPE) 
@Retention(RetentionPolicy.RUNTIME) 
@RestController 
@RequestMapping(value = "/rest", path = "/rest") 
public @interface MyRestController { }

Upvotes: 15

Views: 35782

Answers (4)

Kyle Anderson
Kyle Anderson

Reputation: 7031

Option 1: Custom Annotation

Create a Custom Annotation that declares the base URL and use that in lieu of @RestController.

CustomRestControllerAnnotation.java

package com.example.stackoverflow.config;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@RestController
@RequestMapping("/rest")
public @interface CustomRestControllerAnnotation {}

FirstRestController.java

package com.example.stackoverflow.controller;

import org.springframework.web.bind.annotation.RequestMapping;

import com.example.stackoverflow.config.CustomRestControllerAnnotation;

@CustomRestControllerAnnotation
public class FirstRestController {

    @RequestMapping("/first")
    public String firstMethod(){
        return "First Controller";
    }
}

SecondRestController.java

package com.example.stackoverflow.controller;

import org.springframework.web.bind.annotation.RequestMapping;

import com.example.stackoverflow.config.CustomRestControllerAnnotation;

@CustomRestControllerAnnotation
public class SecondRestController {

    @RequestMapping("/second")
    public String secondMethod(){
        return "Second Controller";
    }
}

Option 2: Base RestController

By creating a Base Controller that serves as a template for all of your actual Controllers, you can effectively manage the root URL from a single location.

BaseRestController.java

package com.example.stackoverflow.controller;

import org.springframework.web.bind.annotation.RequestMapping;

@RequestMapping("/rest")
public class BaseRestController {}

Then you simply extend this class for all of your actual Controllers.

FirstRestController.java

package com.example.stackoverflow.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class FirstRestController extends BaseRestController{

    @RequestMapping("/first")
    public String firstMethod(){
        return "First Controller";
    }
}

SecondRestController.java

package com.example.stackoverflow.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SecondRestController extends BaseRestController{

    @RequestMapping("/second")
    public String secondMethod(){
        return "Second Controller";
    }
}

Option 3: Spring Data REST

If your Controllers are serving Data from a Repository, then Spring Data REST can take out much of the boilerplate & solve your initial problem.

pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>

By declaring this dependency, all of your Repositories automatically become REST enabled.

You can control the base URL by using a property file.

application.properties

spring.data.rest.basePath=/rest

Upvotes: 31

ankit.vishen
ankit.vishen

Reputation: 1170

Updated config for Spring Boot v2.1.0

In Spring Boot v2.1.0 you can configure base URL in application.properties like

server.servlet.context-path = /baseApiName

Complete property configuration list

Upvotes: 5

Adam Madoyan
Adam Madoyan

Reputation: 145

You should add server.servlet-path=/api on your application.properties file and all requests you should send like domain/api/users/{id}

Upvotes: -3

Jan B.
Jan B.

Reputation: 6448

Typically you would define a servlet that handles all (or a particular set) of your restful requests. You would then tell that servlet to listen to a particular URL pattern like /rest. The @RequestMapping annotations of your controllers are unaware of that 'top level' pattern.

For instance, when bootstrapping your Spring Web Application, you could create that restful servlet manually and add a mapping. The whole setup is a little too large to be posted here, but find a snippet below to get a notion.

import org.springframework.web.servlet.DispatcherServlet;
import javax.servlet.ServletContext;
...

public class WebAppInitializer implements WebApplicationInitializer {

   public void onStartup(ServletContext servletContext) throws ServletException {
     ...
     ServletRegistration.Dynamic restfulServlet = servletContext.addServlet("myServlet", new DispatcherServlet(rootContext));
     restfulServlet.addMapping("/rest/*");
     ...

   }

Upvotes: 1

Related Questions