I see a lot of Jersey-based web services consisting of 1+ WebResources
that have 1+ endpoints/methods like so:
package com.myws.fizz;
public class FizzResource {
@GET
@Path("/fizz/{id}")
public Response getFizzById(@PathParam("id") Long id) {
// ...etc.
}
@GET
@Path("/fizz")
public Fizz getFizzByFoo(Foo foo) {
// ...etc.
}
}
package com.myws.buzz;
public class BuzzResource {
@POST
@Path("/buzz")
public Response createBuzz(Buzz buzz) {
// ...etc.
}
}
- I'm confused with what Jersey considers a "resource". Is there a relationship between a "resource" and a database? A table? A POJO?
- When do you return a
Response
vs. a POJO? Look at my 2getFizz
methods above. When do I return aFizz
and when do I return aResponse
?
The term "Resource" isn't so much just a Jersey term, as it is a REST term. When dealing with REST, we have Resources and Representations. A resource can be anything, and in this context, it is some object located on the server, with a URL location. When a client requests for a resource, we send back a representation of it. You ask:
It could be a database (that's a thing). And we could simply represent it as a JSON object with the name of the database. Also it could be a table (that's a thing). And we could represent it as a JSON object with the name and column names. It could be a row in a table, and we could represent that with a JSON object with the column names as the keys and the row values as the JSON values. It could be a web page, an image, whatever. So hopefully you get the point that a resource can be anything. What we send back is its representation.
But the term resource is not just limited to returning something to a client request. The client could also send us a representation of a resource, to say create a new resource (POST) or change an existing resource (PUT). The client may send us a JSON representation of a row (resource) in our database.
Returning
Response
allows you to fine tune theResponse
. When the client make a request, they always get back a response. Responses have headers, and entity bodies. When the return type of the resource method isFizz
, you are saying the entity body type will be aFizz
type. When the method returns, what actually happens is that theFizz
object isn't directly returned to the requesting client, all by itself. Behind the scenes, it gets wrapped in aResponse
that get's sent back to the client. The framework will set the headers it feels appropriate.So whether we decide to return a
Response
orFizz
, it will get wrapped in aResponse
. And like I said, when we return aResponse
, it allows us to fine tune theResponse
, adding our own headers, status codes and such. For example, say someone make aPOST
. You could do something likeBasically what this does is create the resource, say in the database, and we get a return id. We can use the id to concatenate to the URI to the id, this will be the new resource location. In terms of the
Response
,.created(...)
is saying that the status code should be201 Created
, and the value we pass to thecreated
method is the location of the newly created resource. This location will be set as theLocation
header in the response. So lets say that the path to the POST request ishttp://blah.com/buzz
. What we would send back ishttp://blah.com/buzz/100
, where100
is thebuzzId
, and this complete URL is how we will access the buzz resource say with a GET requesst to a resource method annotated with say@GET @PATH("/buzz/{id}")
In terms of a
GET
, with aResponse
, we could doThis is really not so much different than just returning the
newFizz
from the method, because we aren't doing anything special with theResponse
. We're just saying the status code should be200 OK
and attaching the entity body. This is what normally happens with a successful GET request. So if we just return theFizz
, instead of aResponse
, in the case of a successful GET, the framework will implicitly attach a 200 OK status.Personally, I prefer to return
Responses
, because of the fine tuning factor.