15

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 { }
Adam Madoyan
  • 145
  • 1
  • 1
  • 6
  • Possible duplicate of: http://stackoverflow.com/questions/32927937/how-to-set-base-url-for-rest-in-spring-boot – patrykos91 Jul 06 '16 at 08:15

4 Answers4

30

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
Kyle Anderson
  • 6,801
  • 1
  • 29
  • 41
4

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

ankit.vishen
  • 1,100
  • 15
  • 29
  • spring boot version 2.1.4.RELEASE, spring.mvc.servlet.path=/api and server.servlet.context-path=/api , both works – Pramod Kumar Sharma May 08 '19 at 20:22
  • 4
    The question was about rest controllers only. The context path applies to everything. – Tom Jul 14 '19 at 10:44
  • @Tom please explain a bit more, which components will be impacted apart from controllers. As per my understanding, it will set base URL for every restcontroller. – ankit.vishen Jul 16 '19 at 06:43
  • There's a difference between \@RestController and \@Controller. The question implies a base url is wanted for all \@RestController, not \@Controller. Also for example the context-path will apply to ws \@Endpoint annotated soap endpoints as well. – Tom Jul 16 '19 at 10:01
1

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/*");
     ...

   }
Jan B.
  • 6,030
  • 5
  • 32
  • 53
-3

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

Adam Madoyan
  • 145
  • 1
  • 1
  • 6