Design: ensuring clean separation of rendering of a response from a response - java

This is a design / patterns problem. I have a service which now also needs
to be exposed as a RESTful web service.
Within the existing code i have the concept of a Request, a suite
of possible ServiceOperations (strategies) and the return of any ServiceOperation is
a Response object. This approach decouples the inner workings of the
service from the presentation medium (Custom TCP Server, HTTP REST, HTTP
SOAP etc.).
I've now started to implement a MyServiceRESTfulServlet which looks something
like this:
public void doGet(HttpRequest httpRequest, HttpResponse httpResponse) throws ServletException, IOException {
try {
/* Wrap an http servlet request with an adapter which hides all
* the messy details of an HttpRequest and exposes a nice interface
* for working with MyService
*/
IRequest serviceRequest = new MyServiceRESTfulRequest(httpRequest);
/* There's nothing HTTP related in this part, it's the exact same
* code you'd find in other presentation formats. A Response has
* no idea about HTTP, TCP Servers or the like.
*/
Response serviceResponse = dispatchRequest(serviceRequest);
/* A static helper which knows the interface of a Response
* and can translate that into REST-speak for feeding back via
* an HttpServletResponse.
*/
renderRESTfulResponse(serviceResponse, httpResponse);
} catch (Exception e) {
throw new ServletExcetion(e); // Caught by a seperate
// RESTfulErrorServlet
// configured in web.xml
// Rendering an appropriate
// response.
}
}
My problem is a Response can be one of 2 kinds currently:
public enum ResponseKind() {
BINARY, METADATA;
}
For binary, my restful response helper will render one way, for metadata
it will need present the metadata appropriately - an HTML table, a JSON
blob, etc.
Figuring out what type is easy - a Response object exposes a
getOriginalRequest() which after appropriate checks can be cast to a
MyServiceRESTfulRequest which exposes a .getAcceptablePresentation() - an
enum:
public enum RESTPresentationKind() {
HTML, JSON, XML, PROTOBUF_MYSERV_0.1;
}
How best can i keep this rendering code decoupled from a Response object.
In future no doubt other kinds of response will be possible. As is,
renderRESTfulResponse() goes raiding through the Request object and builds
writes out the data appropriately. It's very tightly coupled to both the
Response interface (which i'm ok with) but it knows to go poking through
the Request object too.
I just don't feel i've done this bit in as clean and maintainable a way
as i have the rest of this service. I'm "special casing" for each of the
possible response types, and each of the possible response formats. Feels
uber-hacky.
Can you suggest any way to cleanly process rendering a RESTful response
given a presentation-agnostic Request object?

Why not implement the rendering on your RepsonseKind enum (enums are really classes) or dispense with ity entirely? When you find yourself trying to get rid of case/switch statements, the answer is usually either composition + overloading + Command pattern or the Visitor pattern.

Related

Mocking inbound Jax-RS Response with Entity

I am trying to unit test a class that uses Jersey 2 Client + Moxy to call a REST service. I want to mock the response, which contains a large JSON object. The code is structured in such a way that I can override/mock the following method:
protected Response doPost(String path, Entity<?> entity) {
Invocation.Builder invocationBuilder = getRestInvocationBuilder(path);
Response response = invocationBuilder.post(entity);
return response;
}
I would like to somehow inject some example JSON data (ideally from a file) into the Response at this point, prior to readEntity() being called, so that I can test that the JSON data is correctly unmarshalled into the target object.
Is there any way to do this? Note that this is for unit testing and therefore I'm not interested in running a local server or other integration testing techniques.
I'm aware similar questions have been asked, but many seem out of date or have incomplete solutions. The closest solution suggested is to mock the readEntity() method of the Response, this will not work for me because it would involve creating an object of the desired type to return, rather than creating one from the example JSON data.

How to support batch web api request processing using Spring/Servlets

We have our Web API written in using RESTEasy. We would like to provide support for Batch requests processing the way Google Batch request processing works.
Following is the approach which are using currently,
We have a filter which accepts incoming multipart request. This filter then creates multiple mock requests and response objects and then calls chain.doFilter using these mock requests.
public class BatchRequestProcessingFilter extends GenericFilterBean {
#Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)req;
MockHttpServletRequest[] mockRequests = BatchRequestProcessorUtils.parseRequest(request);
MockHttpServletResponse[] mockResponses = new MockHttpServletResponse[mockRequests.length];
for(int i=0 ; i <= mockRequests.length ; i++ ) {
chain.doFilter(mockRequests[i], mockResponses[i], chain);
}
BatchRequestProcessingUtils.populateResponseFromMockResponses(res, mockResponses);
}
}
MockHttpServletResponse class returns a dummy OutputStream which wraps ByteArrayOutputStream.
BatchRequestProcessorUtils parses the multipart request and returns the mock request which wraps actual request but returns the header specified in split body of the actual request body.
I could not find any existing library which supports batch request processing. So my question is that, is this the correct approach to support batch request or is there any standard way which should be used?
Note that we are using Tomcat 8.
Sachin Gorade. I have not heard about such libraries, but I think your approach is reasonable. If I had to solve that problem, I would think like this:
In our HTTP servlets we can process requests only separately, and it is the reason why we should wrap all requests, that we want to send, into another single request at client side.
As on our server side we have only one request, then we should unwrap all requests we have put into it. And, because we dont know how to process each request in our batch mechanizm - we shold send it through all filters/servlets. Also it is a reason to put our batch filter at the first position in the order.
Eventually, when all requests has been processed, we should send a response back to the client. And again, to do that we should wrap all responses into a single one.
At the client side we should unwrap responses and send each of that to some objects, that can process it.
In my oponion there should be two mechanizms:
Batch sender for client side, that is responsible for collecting and wrapping requests, unwrapping responses and sending them to theirs processors(methods that process regular responses).
Batch processor for server side, that is responsible for unwrapping requests, and collecting and wrapping responses.
Of course, that two parts may be coupled (i.g. to have shared "Wrapper" module), because objects we must be wrapped and unwrapped in the same way.
Also, if I worked on it, I would try to develop the client side mechanizm like a decorator upon a class that I use to send regular requests. In that case, I would be able to substitute regular/batch mode anytime I need to do it.
Hope my opinion is helpful for you.

Jersey Viewable with Json

The JAX-RS implementation Jersey supports MVC style web applications through the Viewable class, which is a container for a template name and a model object. It is used like this:
#GET
#Template
#Produces({MediaType.TEXT_HTML})
public Viewable get() {
JsonObject response = null;
try{
response = service.getDetails(id);
}
catch(Exception ex) {
log.error("failed to get details", ex);
throw ex;
}
return new Viewable("/test", response);
}
this is right way to send the json from Viewable? Is there a way to set a json object explicitly?
A few things: I don't have any experience using Viewable in particular, but I am familiar with JAX-RS and can probably throw a couple of pointers your way.
Exception Handlers
JAX-RS defines a feature for mapping exceptions to responses. This functionality is nice for removing those exception blocks from your resource code. Check out the Jersey docs on this topic for a tutorial on how to register these. A quick summary is: 1) implement ExceptionMapper and 2) register the class as a Provider.
For starters, I recommend creating a simple suite that maps to common HTTP codes. For example:
NotFoundException - returns a 404 response and is used when a single entity is requested but not found.
InvalidInputException - returns a 422 response and is used when a request does not pass validation (like trying to save an phone number in an email field).
BadRequestException - usually the framework will handle these situations for you, but if not, a Bad Request is one that is not formatted properly. So if a required header is missing, or if a client tries to save a collection when only a single entity is allowed.
Exception* - There is a star here because an unexpected exception is usually due to a server error, so 500 is an appropriate default response. A reason you may want to create a global uncaught exception handler is to prevent the stacktrace from being returned in the response body. That can be bad for security reasons.
View and Model
You should not need the #Template annotation if you are using the Viewable object. Also, Viewable is expecting a template as the first argument and a model (map) as the second argument. The model should have keys that match variables in your JSP. Right now your method will look for a file called test.jsp in the root of whatever your template config is set to in web.xml. If you take all of that into consideration, your method could look something like this:
#GET
#Produces(MediaType.TEXT_HTML)
public Viewable getMobileReport() {
return new Viewable("/test", service.getMobileReport(id));
}

Best practices for method types in JAX-RS

What are the best practices regarding the method types in JAX-RS ?
I am interested in the following methods: GET, POST, PUT and DELETE.
My possible approaches:
GET - always return a response.
#GET
#Path("/path/{something}")
public T getT() {
...
return t; // t - instance of T
}
POST
#POST
#Path("/path")
public T/void createOrUpdate() {
...
return t; // t - instance of T
}
Q: Is it better to return the entire created resource or just an "ACK response" or to have a void method? What about a POST that is used as GET (when we want to avoid the URL length limitation)?
PUT
#PUT
#Path("/path")
public T/void createOrUpdate() {
...
return t; // t - instance of T
}
Q: Is it better to have a void method or a response for the created/updated resource or different responses for creation / update or just an ACK response ?
DELETE
#DELETE
#Path("/path/{something}")
public T/void deleteT() {
...
return t; // t - instance of T
}
Q: Is is better to have a void method or to return the deleted resource or to return an ACK response ?
Is it ok to always have T = javax.ws.rs.core.Response (when T is used)?
I saw that:
Lars Vogel uses GET - T, POST - void, PUT - T, DELETE - void
Oracle uses GET - T, POST - T/void, DELETE - void
JAX-RS is a specification for developing RESTful Web Services with Java. There is a reference implementation that is included in Java EE but since it is a specification, other frameworks can be written to implement the spec, and that includes Jersey, Resteasy, and others.
JAX-RS as such does not lay down any guidelines on the return types and response codes for the REST API's. However, there are a few guidelines (these are not hard and fast rules) in the REST standard which you might want to follow:
Method GET
Successful Response RETURN the resource with 200 OK
Failure Response RETURN appropriate response code
Method POST
Successful Response RETURN the link to the newly created resource in Location response header with 201 status code
Failure Response RETURN appropriate response code
Method PUT
Successful Response RETURN the updated resource representation with 200 OK or return nothing with 204 status code
Failure Response RETURN appropriate response code
Method DELETE
Successful Response RETURN nothing with 200 or 204 status code
Failure Response RETURN appropriate response code
In practice, POST works well for creating resources. The URL of the newly created resource should be returned in the Location response header. PUT should be used for updating a resource completely. Please understand that these are the best practices when designing a RESTful API. HTTP specification as such does not restrict using PUT/POST with a few restrictions for creating/updating resources. Take a look at Twitter REST API best practices that summarizes the best practices for RESTful API's.
This answer is not correct/up to date. Please check #ROMANIA_engineer answer instead.
You should never return void. The best practice is to always return a javax.ws.rs.core.Response. But note that even if you define the webresource with void, your server will return a HTTP response.
On POST and PUT, it may be better to return the modified resource, including its id. Some front-end framework and/or middleware will use it to synchronise the resource with your server (as instance, see Backbone Model).
On DELETE, it depends of the action you try to achieve.. But usually an ACK is enough.
NB : Anyway, whatever you return, don't forget to respect your security policies !
Response #Atul : When you send HTTP Request from client or HTTP Response from your server, some data may be protected. As instances :
On user update (username, password, or anything else) do not return the user password in the HTTP Response.
When user log in, you better use a HTTPS protocol and never send the password in plaintext
.. etc
I give it a shot and state a "no there is no best practice". This because the underlying protocol (HTTP) actually has return values (such as 200-OK, 500-Internal Error...) in any case unless a broken connection which should be followed by your service as well.
Since you are not implementing the HTTP-Protocol but a own-designed service following its own rules, no there is no best practice, you will have to define "your protocol" in a way it matches your day to day business the best.
For example when it comes to your delete operation a caller could either not be interested in a response at all or as well expect you to work like a stack and return him the "deleted/removed" element on call. It is up to you to know what fits your needs best.

GWT RequestFactory client scenarios

My understanding is that the GWT RequestFactory (RF) API is for building data-oriented services whereby a client-side entity can communicate directly with it's server-side DAO.
My understanding is that when you fire a RF method from the client-side, a RequestFactoryServlet living on the server is what first receives the request. This servlet acts like a DispatchServlet and routes the request on to the correct service, which is tied to a single entity (model) in the data store.
I'm used to writing servlets that might pass the request on to some business logic (like an EJB), and then compute some response to send back. This might be a JSP view, some complicated JSON (Jackson) object, or anything else.
In all the RF examples, I see no such existence of these servlets, and I'm wondering if they even exist in GWT-RF land. If the RequestFactoryServlet is automagically routing requests to the correct DAO and method, and the DAO method is what is returned in the response, then I can see a scenario where GWT RF doesn't even utilize traditional servlets. (1) Is this the case?
Regardless, there are times in my GWT application where I want to hit a specific url, such as http://www.example.com?foo=bar. (2) Can I use RF for this, and if so, how?
I think if I could see two specific examples, side-by-side of GWT RF in action, I'd be able to connect all the dots:
Scenario #1 : I have a Person entity with methods like isHappy(), isSad(), etc. that would require interaction with a server-side DAO; and
Scenario #2 : I want to fire an HTTP request to http://www.example.com?foo=bar and manually inspect the HTTP response
If it's possible to accomplish both with the RF API, that would be my first preference. If the latter scenario can't be accomplished with RF, then please explain why and what is the GWT-preferred alternative. Thanks in advance!
1.- Request factory not only works for Entities but Services, so you could define any service in server-side with methods which you call from client. Of course when you use RF services they are able to deal with certain types (primitive, boxed primitives, sets, lists and RF proxies)
#Service(value=RfService.class, locator=RfServiceLocator.class)
public interface TwService extends RequestContext {
Request<String> parse(String value);
}
public class RfService {
public String parse(String value) {
return value.replace("a", "b");
}
2.- RF is not thought to receive other message payloads than the RF servlet produces, and the most you can do in client side with RF is ask for that services hosted in a different site (when you deploy your server and client sides in different hosts).
You can use other mechanisms in gwt world to get data from other urls, take a look to gwtquery Ajax and data-binding or this article

Categories