1

I have the following REST endpoint:

@POST
@Path("/id/{id}/doSomething")
@Produces({ MediaType.APPLICATION_JSON })
@Consumes({ MediaType.APPLICATION_JSON })
public Response doSomething(@PathParam("id") final String id, MyObject foo) {
    // does some stuff; checks for a null foo and handles it
}

The MyObject class has a single String field called justification.

I'd like to be able to hit this endpoint with no content at all, or with JSON that maps to the MyObject class. I'd like either way to work. In other words, foo can be instantiated, or foo can be null; I have code to handle both cases.

The problem is that the JSON content appears to be required to this endpoint, not optional. So during testing, I'm having to send JSON to the endpoint, or I receive a 500 error. Even if that JSON is just {} (I can also send { justification: "blah blah" } and that works as well). But sending no content at all results in a failed call; never even hits the endpoint.

So, my question is, how can I set this endpoint up so that I can POST to it with no content at all, or with JSON in the body that maps to foo, and have either way work?

Ultimately, I just need a way for the user to be able to send a justification to this endpoint, but not have to. And because justifications can be long, I can't have it as a query param or a path param.

Thanks!

Matt
  • 23,363
  • 39
  • 111
  • 152

2 Answers2

2

You are not going to be able to hit the endpoint with no content at all because your endpoint says @Consumes({MediaType.APPLCIATION_JSON}). Besides there has to be some content while you're trying to POST to a class while using a web service. Like you said, even if it is a NULL or a {}, it doesn't matter as long as it has some content coming in. Passing no content to the service works only when you're making a GET request. For all other HTTP methods such as POST,PUT and DELETE, you will mandatorily HAVE to send some data. As a solution to your problem, what you possibly could do is that - check if the content you have received is a NULL or a {} and do no processing at all for them.

If you still have a confusion in the answer, depending upon whether you're using SOAP or REST, this thread should help you. How to express 'null' value from web service as real null or empty string instead of 'null' string Hope this helps.

Community
  • 1
  • 1
TheLuminor
  • 1,411
  • 3
  • 19
  • 34
  • Wouldn't be satisfactory for me because that means having the UI pass in at lease `{}` every time. Fundamentally, that seems hacky to me. I found a solution that sort of disproves what you suggested, but I may be misunderstanding your response. I'm about to post it, so, respectfully, you're welcome to provide comments. – Matt Sep 25 '15 at 02:41
  • 1
    Sure! Since you say you have found a post, maybe my solution is wrong too. Do post it, will take a look :) – TheLuminor Sep 25 '15 at 02:45
  • Posted. Let me know what you think. – Matt Sep 25 '15 at 02:52
2

I was able to accomplish what I wanted by writing a second method annotated with the same REST path. This second method does not have an @Consumes statement, and does not have the second parameter in its method declaration. Looks like this:

@POST
@Path("id/{id}/doSomething")
@Produces({ MediaType.APPLICATION_JSON })
public Response doSomethingWithoutJustification(@PathParam("id") final String id) {
    doSomething(id, null);
}

This new method maps to the same path, but does not expect JSON and doesn't expose a second parameter. So when I POST with nothing in the request body at all, it hits doSomethingWithoutJustification, and when I do provide JSON in the request body, it hits doSomething. Of course, if I provide anything other than valid JSON in the request body, I receive a 500 response from the service, as I'd expect.

I'd hoped to specify an optional parameter with a single method, but this solution works perfectly.

Matt
  • 23,363
  • 39
  • 111
  • 152