Tuesday, January 29, 2013

RESTful url - few tips


Many beginners associate REST url’s with url having some identifier to identify the resource even if the identifier is present in the url parameter.
For e.g.,

http://www.myshop.com/shopping/products?productid=1

Here the url seems to be identifying a resource (product) with an identifier (productid) 1
However technically this is not a RESTful url.

REST ways of looking at resources says that the web is a web of information resources on which you can take standard actions.  HTTP is a good example of REST with the resources identified by url’s and the standard actions on those resources are GET, POST, PUT, and DELETE. The most predominant operations done in HTTP is to get the resource representation using GET and make updates to it using POST.

A resource oriented RESTful  url must serve as an unique identifier without the additional parameters, meaning the url itself should have the identifier in itself, something like this

http://www.myshop.com/shopping/products/1

Another important distinction is that the url must not include any verb rather only nouns because the verbs (actions that could be performed) are already defined as standard actions. For e.g., have a look at this url.

http://www.myshop.com/shopping/getproducts/1

Some frameworks might make use of this kind of url to map a method “getproducts” in the controller and pass the identifier 1. However this cannot be taken as a true resource identifier as it includes a part “getproducts” which has nothing to do to identify a resource. So in essence a RESTful url should be a resource oriented url which uniquely identifies a resource.

Monday, January 28, 2013

Spring MVC Framework - SessionAttributes annotation



Spring MVC is a highly configurable web framework. It can be configured using xml or now more popular annotations. Spring MVC is very powerful , however the number of different ways in which a single thing can be done can be sometimes overwhelming.  I have found it extremely useful to have Spring framework source code in my IDE and go through it whenever I need to know the internals. Of course technical blogs and discussions on StackOverFlow site has always been very helpful. Today I am going to discuss about an important annotation called SessionAttributes.
This annotation is declared at type level on the Controller class.
You specify SessionAttributes annotation like this:

@Controller
@RequestMapping("/editPet.do")
@SessionAttributes("pet")
public class EditPetForm {
    // ...
}

As you can see that you mention just the attribute name. This is a signal to the framework that whatever object is stored against the attribute named “pet” in the Model during the processing of the handler, it will be available as long as the methods are being called in the same controller.
Now the question is who creates / stores the object corresponding to this attribute.
You may remember that a controller may contain a method annotated with @ModelAttribute which means that the method will be called before any handler method is called. Also that method stores the return value in the Model against the model attribute name specified by @ModelAttribute.
Also a handler method may contain an argument annotated by @ModelAttribute which means that the framework will inject that attribute from Model if present or create new. So when you add a @ModelAttribute("pet") controller method argument you're telling Spring MVC to look for it in the model or create a new instance if not found. But  if you also add @SessionAttributes, at controller class level framewotk will not attempt to create a new instance and will expect the object to be either in the model or in the session.

So now armed with this knowledge let’s recreate the steps

1.  Our controller class is annotated with @SessionAttribute name “pet”
2.   A method in controller class is annotated with @ModelAttribute named “pet” and it returns a Pet object usually from  database. We do not want to load it again when next time this method is called.
3.   Because of point 1, the model attribute “pet” is available not only in the view but it is also stored session so that when again the handler method annotated with @ModelAttribute(“pet”) is called, it is injected by framework
4.   Also we would like such conversational attributes to be removed from session when the conversation ends. To accomplish this we can declare an argument of type SessionStatus in the handler method and framework will inject it into the handler method. We can then call setComplete() method on SessionStatus to indicate that the attributes need to be cleared.

So then what is the difference between storing an attribute in HttpSession and SessionAttribute.
An object stored in http session will be there till the life time of http session. Now imagine that in the above mapping example for /editPet.do, the “pet ” attribute is a Pet object loaded from database through a method annotated with @ModelAttribute  in the controller class. We probably need the Pet object for the time as long as we are doing some processing logic for the editing. All such methods doing this processing logic should ideally be in the same controller.
So @SessionAttribute along with SessionStatus provides a way to make the “pet” attribute available while the methods of ONLY this controller are being called. That also means that session attributes using @SessionAttributes are not available across controllers while attributes stored in HttpSession are always available. So in nutshell we can say that attributes specified by @SessionAttributes are meant for storing conversation related objects into http session for conversation time period.