Tuesday, January 24, 2012

RESTful standard resolved! - part I

Latly I'm trying to build a web application which will be exposed in a RESTfull manner.
There are some general guideline and hints about how to define it, but no explicit standard or accepted schema structure to use.

After reading some info on the web, I think I manage to crack the pattern :-)
I would like to share the rules and structure I formed and hopefully to get some feedback about it and improve it, so please don't hesitate to leave notes and point any pain point that structure has.

The high level pattern is:
http(s)://server.com/app-name/{version}/{domain}/{rest-convention}

Where {version} is the api version this interface work with and {domain} is an area you wish to define for any technical (e.g. security - allow certain users to access that domain) or business reason (e.g. gather functionality under same prefix).

The {rest-convention} denotes the set of REST API which is available under that domain.
It has the following convention:

  • singular-resourceX/
    • URL example: order/  (order is the singular resource X)
      • GET - will return a new order
      • POST - will create a new order. values are taken from the post content body.
  • singular-resourceX/{id} 
    • URL example: order/1 (order is the singular resource X)
      • GET - will return an order with the id 1
      • DELETE - will delete an order with the id 1
      • PUT - will update an order with the id 1.  Order values to update are taken from the post content body.

  • plural-resourceX/
    • URL example: orders/
      • GET - will return all orders
  • plural-resourceX/search
    • URL example: orders/search?name=123
      • GET - will return all orders that answer search criteria (QBE, no join) -order  name equal to 123
  • plural-resourceX/searchByXXX
    • URL example: orders/searchByItems?name=ipad
      • GET - will return all orders that answer the customized query - get all orders  that associated to items with name ipad
  • singular-resourceX/{id}/pluralY
    • URL example: order/1/items/ (order is the singular resource X, items is the plural resource Y)
      • GET - will return all items that associated to order #1
  •  singular-resourceX/{id}/singular-resourceY/
    • URL example: order/1/item/
      • GET - return a new item (transient) that is associated order #1
      • POST - create a new item and associate it to order  #1. Item values are taken from the post content body.
  •  singular-resourceX/{id}/singular-resourceY/{id}/singular-resourceZ/
    • URL example: order/1/item/2/package/
      • GET - return a new package (transient) that is associated to item 2 (i.e. how to pack the item) and is associated to order #1
      • POST - create a new package and associate it to item #2 & order #1. package values are taken from the post content body.

One basically can have further nesting as long as the above convention is maintained and no plural resource is defined after another plural resource.
There are further guidelines/notes to make things clear:
- When using plural resource, the returning instances will be those of the last plural resource used.
- When using singular resource the returning instance will be the last singular resource used.
- On search, the returning instances will be those of the last plural entity used.

Hopefully your insight will help me improve this structure and overcome issues which you might came across.

In next post, after this suggested structure will be improved, I will try to give technical examples how to implement it using Spring MVC 3.1


Friday, January 20, 2012

Advanced QBE pattern (common using generics)

On previous post I introduced the QBE pattern.

The pattern saves us a lot of tedious binding code.
However, one still need to implement the same method for each Entity.

To save us the redundant work of defining the same QBE method for each entity, where only the entity is changed, we could utilize Generics.

Using Generics we will implement only one method in a base class, and each concrete QBE (on certain @Entity) will inherit from that base class.


Lets see that in action.

First, we define the interface for the base class:

public interface BaseDAO {

   

    /**
     * Perform a query based on the values in the given object.
     * Each (String) attribute will be searched based on the Like comparison.
     * Comply the QueryByExample (QBE) pattern
     * @param modelEntity The Entity with values to search
     * @param propertiesToExclude Any property which the search will ignored.
     * @return Instances that answer the given parameters values (empty if none)
     */
    public List getByElementsLike(T modelEntity, List propertiesToExclude);   

    /**
     * Perform a query based on the values in the given object.
     * Each attribute will be searched based on the Equality comparison.
     * Comply the QueryByExample (QBE) pattern
     * @param modelEntity The Entity with values to search
     * @param propertiesToExclude Any property which the search will ignored
     * @return Instances that answer the given parameters values (empty if none)
     */
    public List getByElementsEqual(T modelEntity, List propertiesToExclude);

}



 Second step is to write the Base class implementation

public class BaseDaoImpl implements BaseDAO {
//Get DB session access using Spring 3.1 Entity Manger
     @PersistenceContext
    protected EntityManager em;
  
    protected Class entityClass;

   
     //Initialize the entity class
     @SuppressWarnings("unchecked")
    public BaseRepositoryImpl() {
            ParameterizedType genericSuperclass = (ParameterizedType) getClass().getGenericSuperclass();
            this.entityClass = (Class) genericSuperclass.getActualTypeArguments()[0];
        }

    protected Class getEntityClass() {
        return entityClass;
    }   
  

    public List getByElementsLike(T modelEntity,List propertiesToExclude) {

        // get the native hibernate session
        Session session = (Session) em.getDelegate();

        // create an example from our model-entity, exclude all zero valued numeric properties
        Example example = Example.create(modelEntity).excludeZeroes().enableLike(MatchMode.ANYWHERE);

        for (String property : propertiesToExclude) {
            example.excludeProperty(property);
        }       

        // create criteria based on the customer example
        Criteria criteria = session.createCriteria(getEntityClass()).add(example);

        // perform the query       
        return criteria.list();

    }

    public List getByElementsEqual(T modelEntity,List propertiesToExclude) {

        // get the native hibernate session
        Session session = (Session) em.getDelegate();

        // create an example from our customer, exclude all zero valued numeric properties
        Example example = Example.create(modelEntity).excludeZeroes();

        for (String property : propertiesToExclude) {
            example.excludeProperty(property);
        }   

        // create criteria based on the customer example
        Criteria criteria = session.createCriteria(getEntityClass()).add(example);

        // perform the query       
        return criteria.list();
    }

}


Third step is to extend the base class:
@Entity

public class Order{
..
}

 

@Entity
public class Item{
..
}

 
public class OrderDaoImpl extends BaseDaoImpl implements
        BaseDao{

//No need to implement the QBE again here

}

public class ItemDaoImpl extends BaseDaoImpl implements
        BaseDao{

//No need to implement the QBE again here

}


Kindly let me know for any further improvements.

QBE pattern

When writing an enterprise system, there is a common pattern of a user who fill in a search form and get a corresponding result based on the given search parameters.

Handling this request manually in the backend is a bit tedious since for every search parameter, the developer need to check if the user insert a value and if so, concatenate the corresponding string into the WHERE clause in the SQL.

The Query By Example (QBE) pattern is a pattern that helps deal with the mentioned task.

It is implemented by ORM frameworks (such as Hibernate) and also avlaiable as part of possible to implement utilizing the the spec in JPA 2.0 (as seen in OpenJPA project)

The QBE implementation expect the model instance (the object which is annotated with @Entity).
That instance should have the form search values in it.
Than the implementation  framework does all the SQL wiring magic and save us the tedious work.
So at the end we just return the query result.

Lets discuss a case where a user want to query the Order object.

The Order class need to be annotated with @Entity


@Entity
public class Order{
..
}

Using a Hibernate implementation :
public List findByOrderElements(Order order) {

 Session session = getSession();

//Hibernate assembles the query with the given entity to query
 Example example = Example.create(order) //create Example object given the instance to query
     .enableLike(MatchMode.ANYWHERE) //optional parameters
     .excludeZeroes()
     .ignoreCase();

//Get the query result
 List result = session.createCriteria(Order.class)
     .add(example)
     .list();
        
 return result;
}


That's it...

Important note:
  • QBE will only work on one object (won't help in case the form input has properties of other related fields, i.e.  requires join)
  • Version properties, identifiers and associations are ignored (if QBE would consider the id than it would match only one instance...)

For even more advanced stuff regarding QBE pattern, please follow my next post.