4

We are building a new Rest service. I have a PUT method that looks something like this:

   @RestController
   public class RestController...
   .
   .
   @PutMapping("/api/entity1")
    public ResponseEntity<String> entity1Put(@RequestBody Myclass entity,
            @RequestParam(value = "node1", defaultValue = emptyString) String node1,
            @RequestParam(value = "user", defaultValue = emptyString) String user,
            @RequestParam(value = "password", defaultValue = emptyString) String password) {...}

The method is essentially a proxy for calling the business layer of the app. My POST method will have exactly the same signature, preparation code and return type. The only difference will be the name of the method called at the business layer. In order to have less code and promote API consistency, I would like to have a single method that handles both PUT and POST requests.

Is it possible to do this?

   @RestController
   public class RestController...
   .
   .
   @PutMapping("/api/entity1")
   @PostMapping("/api/entity1")
    public ResponseEntity<String> entity1PutandPost(@RequestBody Myclass entity,
            @RequestParam(value = "node1", defaultValue = emptyString) String node1,
            @RequestParam(value = "user", defaultValue = emptyString) String user,
            @RequestParam(value = "password", defaultValue = emptyString) String password) {...} 

If so, then how can I determine the request's HTTP method?

dbreaux
  • 4,982
  • 1
  • 25
  • 64
BigTFromAZ
  • 684
  • 7
  • 22
  • 1
    1. Test it, and you'll know. 2. https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc-ann-arguments – JB Nizet Jul 23 '18 at 17:28
  • I thought of that after posting the question. Received a 405. So multiple methods with comments telling the developers to keep them in sync is the way it will be. – BigTFromAZ Jul 23 '18 at 17:34
  • You can use RequestMapping. It has a method parameter taking an array of methods. – JB Nizet Jul 23 '18 at 17:38
  • I think I can sort that out. How do I test to determine which method was used? – BigTFromAZ Jul 23 '18 at 17:53
  • Which of the arguments accepted by a handler method, listed in the link I posted, could possibly allow you to get the method of the **request**? – JB Nizet Jul 23 '18 at 18:21

1 Answers1

6

It appears I received "-1" for asking a dumb question but that's ok.

Here is a solution after following some pointers provided by @JB Nizet.

Change 1, switched to RequestMapping with an array of methods.

Change 2, being new to Spring, I was unaware that the run time will inject certain types if you ask for them. Added a HttpServletRequest parameter and Spring dutifully provided the request data that I need.

Change 3 altered our business rules layer to accept the method name as a parameter allowing that layer to implement the semantic differences between the PUT and POST.

As a result, engineers working on this code in the future will be more likely to maintain a consistent API for PUT/POST. A useful byproduct of this effort is we can now push request information in addition to performance metrics into our app insights service and the code remains simple.

@RequestMapping(path="/api/entity1", method={RequestMethod.PUT,RequestMethod.POST})
public ResponseEntity<String> entity1PutandPost(@RequestBody Myclass entity1,
        HttpServletRequest request,
        @RequestParam(value = "node1", defaultValue = emptyString) String node1,
        @RequestParam(value = "user", defaultValue = emptyString) String user,
        @RequestParam(value = "password", defaultValue = emptyString) String password) {

    try {
            BusLayer.processObject(request.getMethod(), entity1, creds);
    } 
BigTFromAZ
  • 684
  • 7
  • 22