Home > Mobile >  Same prefix endpoint but two different Controllers
Same prefix endpoint but two different Controllers

Time:10-22

I remember working on a project made in Django where you could create routes that could be given a prefix and then include another URL file for the rest of the endpoint.

api_patterns= [
  url('foo/', include(foo.urls)),
  url('bar/', include(bar.urls)),
]

urlpatterns = [
  url(r'api/', include(api_patterns)),
]

This implementation would result in endpoints /api/foo/ and /api/bar/ and these endpoints would live in separate directories with separate url files.

The question is whether we can implement something equivalent to Spring Boot.

I know you can add the prefix to the @RequestMapping on all the files. But in my current project, we have a lot of controllers that start from the same route prefix and then, later on, differ from each other.

// Foo controller
@Controller
@RequestMapping(path = "api/foo")
public class FooController {

  @GetMapping(path = "")
  // Endpoint to /api/foo
}

// Bar controller
@Controller
@RequestMapping(path = "api/bar")
public class BarController {

  @GetMapping(path = "")
  // Endpoint to /api/bar
}

// Tar controller by foo
@Controller
@RequestMapping(path = "api/foo/tar")
public class TarController {

  @GetMapping(path = "")
  // Endpoint to /api/foo/tar
}

The endpoint would then look like this /api/foo, /api/bar, and /api/foo/tar.

How can I prevent the repeated path prefix on all the files?

This routing might be a bad practice for working with API endpoint, I also think that this could be prevented, and that is why I'm asking as a junior developer to try to improve and show responsibility at my first job.

CodePudding user response:

You probably need to smash the controllers with the same endpoint beginning. I'd suggest you to remain this annotation @RequestMapping(path = "/api/foo") and just insert inside that class the methods with @GetMapping(path = "/tar"). And other methods could have prefix tar: "/tar/example".

But if there are lots of methods starting with this prefix /api/foo/tar and the class FooController begins to be big enough, it's nice to keep them separately.

CodePudding user response:

You can have an interface like below:

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

@RestController
@RequestMapping(path = "/api")
public interface BaseController {
}

Then every individual controller class can implement the interface like below:

public class FooController implements BaseController {
  @GetMapping(path = "/foo")
  // Endpoint to /api/foo
}

Provided it is possible to change every controller class.

CodePudding user response:

I think the best practice would be something like

/**
 * Class for String constants to use in the application
 */
public final class WebConstants {

   public static final String API = "api";
   ...other constants

}

@Controller
@RequestMapping(path = WebConstants.API   "/foo")
public class FooController {

  @GetMapping
  // serve something for /api/foo

  @GetMapping(path = "/tar")
  // serve something for /api/foo/tar

}

// Bar controller
@Controller
@RequestMapping(path = WebConstants.API   "/bar")
public class BarController {

  @GetMapping
  // Serve something for /api/bar
}
  • Related