I have a simple web app which propagates requests to another web app. My web app provides two very similar API's which query the same web app but for different types of information. For instance, my web app takes these two URL's
http://myservice.com:8080/otherservicecall1?userId=(userid)
http://myservice.com:8080/otherservicecall2?accountId=(accountid)
If I want to use the same service and data layer for my web app, what is the best way to differentiate between the two different parameters for these requests? For instance, I have a class in my data layer which handles 404's from the other service, with log messages such as
log.error("Could not find information on userId = " + userId);
But logs and exception messages like this are not generic enough to apply to both types of requests, meaning I have to pass in a parameter type variable which just holds the name of the parameter.
I guess what I'm ultimately asking is, is there a simple way to propagate the name of the parameter that I'm passing in through the controller through the service and data layer without passing it in through every function call? I have thought of making use of enumerations somehow but I can't see how they would help here.
For exceptions, We throw a generic ObjectNotFoundException that has a method that will return the id of an object we're looking for. If we need specialized exception messages we will extend our ObjectNotFoundException with something more specific and then update our Spring SimpleMappingExceptionResolver to handle the new, more specific, exception.
We make sure to keep the most general exception (ObjectNotFoundException) last in the exceptionMapping list.
For services, well, I wouldn't worry about if the parameter is called userid or accountid. The behavior for both those parameters should be the same. If you are worried about it, then your user interface layer is bleeding into your service and persistence layers; Which, is a bad thing.
Related
I'm creating a REST api specifically for serving my android application requests. Some of the operations exposed by the API just queries the database and returns data to be displayed by the app.
However, I would like these operations to return a generic REST response, so that the data queried from the database are displayed on the UI without the need to create a response attribute for each field.
For example, i have an api operation which returns a list of transactions from the database which are displayed inside a list view.The attributes shown inside each list view item depends on the type of the transaction.
So i thought of two approaches for constructing my ResponseTransaction class:
1- Just create an attribute for each database field which needs to be displayed: id, description, amount, time, date, type ... and based on the type , android would detect which attributes to display inside each item.
2- Second approach is to tell android what to display through returning a generic response holding: HashMap(Label, Value) where values represents necessary database fields.
By using the first approach, I should update apk each time i add a new transaction type.However this is not the case in the second approach which just requires a new service deployment.
So do you think that the second approach is the best way to go for creating generic REST responses for the database operations and is it a good practice to couple REST responses to the client if we are sure that the service is only used internally by our android or web application.
Please advise.
I am new to REST and I understand that the idea of resource is central to a RESTful service. Let's say I have created a RESTful service which allows users to create/read/update/delete some objects in my hashmap (an object say CustomerOrder, which has stuff like orderId and a list of dishes they have ordered).
This is easily translated to REST, I have GET to read an order, DELETE to delete one, POST to create a new one and PUT to update.
However, lets say my application has some method called processCustomerOrder(int orderId), which retrieves the order from the map and simply sends the order to another webservice that processes the order. I want my frontend website to have a button 'Process Order' which will call the method and my server will just return a string like "order processed successfully".
Am I right in saying this should simply be another GET method with a different path? e.g.:
path=restservice/processRequest
httpmethod=GET
param=orderId
or does this break the rules of RESTful design because I am not actually getting any resource?
Of course you can do this. In this case, the resource is the method (the method is a resource also, because you can do some processing, return a message or other entity, so it doesn't matter what kind of processing it is about).
String is a valid response entity (JAX-RS Response Entity Types).
You may be interested in subresource method locators: http://docs.oracle.com/javaee/6/tutorial/doc/gknav.html#gklag .
I have a Spring Web MVC application where i need to use an external device driver which returns information in an asynchronous manner every time the device gathers some new data. We need to pass an object at the begging to the start read method. This object implements an API defined interface which declares the callback method.
The problem raises when this callback method needs to manipulate some bean in Spring's session scope. Because the callback gets called in the Thread of the driver when the callback implementation wants to access a Spring bean it yields an exception saying that the current thread is not in Spring's managed scope.
I'm wondering if there's any way to make the object which is implementing the callback interface into some kind of proxy which knows information about the context of the session which constructed it so this way it can invoke bean methods through Spring's context object?
I think you are approaching the problem from the wrong side. I guess you want the device driver callback to put some results in the user session. But this is not enough to display that data, so (guessing again) probably some long-polling is involved, looking into the session through session-scoped bean.
With this assumption I advice you to generate some sort of unique requestId every time you call the back-end driver and put that requestId both in the HTTP session and in the callback. When the callback is called, it pushes the results into some sort of map, where key is the assigned requestId. Now the client (who knows the requestId as well) can look into the map and fetch the results. You must remember about the synchronization (which is also the case with normal HttpSession).
If you have some more advanced way of notifying clients (Comet? WebSockets?) this can also be done in this callback.
Note that technically you can pass an instance of HttpSession object into the callback instance (but as you can see this does not work with Spring session-scoped beans) but passing session around doesn't seem like a good design. It is simply better to provide a level of indirection. What if, in the future, you would like to reuse that code with command-line or desktop client?
Say a logged in user hits the url:
www.example.com/forum/234
Before the spring mvc action fires, I want to load the User Object, the user's permission, the Forum object.
Now I want to share these objects accross this request. So other classes can look to see, in the current request, for a User, Permission and Forum object.
Potentially it would be cool if a custom freemarker module could also reference these objects if they are available.
is this possible?
First, consider using spring-security, whose filters do everything you need.
If you want to do all by hand, then you have at least two options:
- use servlet filters
- use spring handler interceptor (http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/mvc.html#mvc-handlermapping-interceptor).
In both cases store this data in request attributes.
Another option is to create bean with request scope which will store your data.
As for Freemarker, you must provide own subclass of FreemarkerViewResolver, which will return subclass of FreeMarkerView in requiredViewClass() method. Add your objects in exposeHelpers() method in this FreeMarkerView subclass.
Design question for using Business Objects as formBackingObjects in a Spring SimpleFormController.
Our controller's responsibility is to allow an End User to add a new Business Object to our web application.
So we are passing our Business Object though the formBackingObject(HttpServletRequest request) method. However, we've run into a conundrum.
The factory that we are using to create our new Business Object enforces the business rules that some of the attributes cannot be null. But since we don't know what the End User wants to enter we've been passing in "reasonable defaults" like "Please enter the name you want", but that seems hackie/icky at best.
What is a developer to do? I feel as though this is the classic chicken/egg problem.
All our Business Object are based off of Interfaces, should we create a Stub that represents the Business Object, pass the Stub as the formBackingObject, and then pass the Stub to the Factory on a Form submit? Or should we not pass anything in the formBackingObject and then manually gather the submitted information from the request?
Any other reasonable ideas/patterns?
Thank you for your time.
I definitely wouldn't choose the option of not using a formBackingObject and gathering the information manually -- that would eliminate a lot of the power that makes Spring MVC worthwhile in the first place.
If I were you, I would just make a new factory, or factory method, that is designed specifically to create an "uninitialized" business object, and use that as your formBackingObject.
Another approach that is widely used is not to use a business object as your formBackingObject at all, but create a separate transport object whose only purpose is to be the formBackingObject (and then add a factory method for your business object that lets you initialize it from the transport object). One of the big advantages of this is if your business object has a deep tree of other objects inside it, this can make it a pain to use as a formBackingObject. If you create a separate transport object just for use as a formBackingObject, you can give it a much flatter structure.
Use a command object (a dead simple POJO) to represent the user's input to your controller. Then you can use the validation built-in to Spring MVC to make sure that all of the required fields are supplied in the command object. If the command passes validation, then you can map it to a your "Business Object" programatically (or using a bean mapping library like Dozer).
This way you can handle validation, incomplete user submissions, etc., without touching or modifying any existing business logic / rules / service classes. This allows you to keep the web layer separate from these existing layers.
For reference, see the MVC tutorial, which touches on validation and command objects in Part 4.