8

I'm converting one of my existing service to become RESTful and I've got the basic things working with RestEasy. Some of my client apps should be able to execute both GET and POST requests to several services. I'm just seeking if there is any easy way around jax-rs to specify that API should accept both GETs and POSTs. Following you can find a test method, let me know if you see any way around without duplicating this in another class with @GET and @QueryParam.

@POST
@Path("/add")
public Response testREST(@FormParam("paraA") String paraA,
        @FormParam("paraB")  int paraB) {

    return Response.status(200)
            .entity("Test my input : " + paraA + ", age : " + paraB)
            .build();

}
Charith De Silva
  • 3,650
  • 4
  • 43
  • 47

3 Answers3

20

Just put your method body in another method and declare a public method for each HTTP verb:

@Controller
@Path("/foo-controller")
public class MyController {

    @GET
    @Path("/thing")
    public Response getStuff() {
        return doStuff();
    }

    @POST
    @Path("/thing")
    public Response postStuff() {
        return doStuff();
    }

    private Response doStuff() {
        // Do the stuff...
        return Response.status(200)
                .entity("Done")
                .build();
    }
}
blong
  • 2,815
  • 8
  • 44
  • 110
  • Thanks b.long for your answer. This is exactly my problem. I need to avoid these method/class duplication. I already have loads of methods in my service which has to accept both POST and GET. I'm seeking for a way to do this with jax-rs annotations itself. – Charith De Silva Nov 15 '12 at 23:58
  • 1
    I don't think it's possible (i.e. explicitly not allowed per the spec.). This blog mentions that you can not use them in conjunction: http://marxsoftware.blogspot.com/2010/02/playing-with-jerseyjax-rs-method.html#post-body-8986464064706467213 – blong Nov 16 '12 at 14:35
  • 4
    Whenever I get the desire to do this, I refactor the worker `doStuff()` into another class/bean so that I have the real API operations and then their presentation. (I also map them out as JAX-WS, as some of my clients prefer that.) – Donal Fellows Nov 20 '12 at 12:25
  • @DonalFellows that's a great way to do it, I actually need to start using your approach! – blong Nov 20 '12 at 14:50
  • Any fully working code for the POST version with Spring Boot? – powder366 Feb 14 '17 at 12:17
4

As wikipedia says, an API is RESTful if it is a collection of resources with four defined aspects:

  • the base URI for the web service, such as http://example.com/resources/
  • the Internet media type of the data supported by the web service. This is often XML but can be any other valid Internet media type providing that it is a valid hypertext standard.
  • the set of operations supported by the web service using HTTP methods (e.g., GET, PUT, POST, or DELETE).
  • The API must be hypertext driven.

By diminishing the difference between GET and POST you're violating the third aspect.

yegor256
  • 102,010
  • 123
  • 446
  • 597
  • As you say, it needs a "set" of supported operations. There are situations where the environment may dictate the necessity of multiple operations e.g. conditional redirects (302) may or may not result in POST or GET operations to a particular service. – Nick Apr 13 '15 at 01:54
0

If this scenario fits for all your resources you could create a ServletFilter which wraps the request and will return Get or Post everytime the method will be requested.

Daniel Manzke
  • 310
  • 2
  • 8
  • ServletFilter is definitely a way of doing it. Check the Example [10.3. Pre-matching request filter](https://jersey.java.net/documentation/latest/filters-and-interceptors.html). The example provides a direct way of manipulating the header of the incoming request. – Robin Keskisarkka May 04 '17 at 06:41
  • The previous link is broken, this one works right now: https://eclipse-ee4j.github.io/jersey.github.io/documentation/latest31x/filters-and-interceptors.html – gouessej Mar 27 '23 at 14:10