Monday, April 27, 2015

The Richardson’s REST Maturity Model (RMM)

While reading the book ASP.NET Web API 2, Building a REST Service from Start to Finish, I came across a maturity model for REST known as the Richardson’s REST Maturity Model. The aim of the maturity model is to define an improvement pathway for developers to build RESTful web services. The pathway is scattered across 4 levels, starting at Level 0 going up to Level 3. Each level defines an improvement to building RESTful web service as follows:

Level 1 – Having unique URI for resources
Level 2 – Using HTTP Verbs to define action
Level 3 – Hypertext Controls known as the acronym HATEOAS (Hypertext as the Engine of Application State)

For the sake of clarity, I will be using an Employee web services and define a list of services/resources/methods exposed by it. At each level, I will demonstrate how the services/resources are improved by applying the principle defined in that level.

Level 0
At level 0, the web service resembles the SOAP/RPC style service. That is, there is a single URL of the web service and it supports a single HTTP verb. To access the different method on the web service, the client will add the specific method name in its header or as a parameter to the request. The following show a list of resources exposed by a level-0 web service

Method on ServerURIHTTP Verb
CreateEmployee/v1/employeService.asmxPOSTInformation via WSDL
GetEmployee/ v1/employeService.asmxPOSTInformation via WSDL
GetEmployeeTask/ v1/employeService.asmxPOSTInformation via WSDL
SearchEmployee/ v1/employeService.asmxPOSTInformation via WSDL
UpdateEmployee/ v1/employeService.asmxPOSTInformation via WSDL
DeleteEmployee/ v1/employeService.asmxPOSTInformation via WSDL


Level 1
At level 1, the aim is to define a particular resource for a corresponding method on the web service and therefore each individual resource is accessed via a unique URI as follows:

Method on ServerURIHTTP Verb
CreateEmployee/ v1/employeePOSTInformation via WSDL
GetEmployee/ v1/employee/225POSTInformation via WSDL
GetEmployeeTask/ v1/employee/225/tasksPOSTInformation via WSDL
SearchEmployee/ v1/employeePOSTInformation via WSDL
UpdateEmployee/ v1/employee/225POSTInformation via WSDL
DeleteEmployee/ v1/employee/225POSTInformation via WSDL


Level 2
In level 1, we have used the HTTP verb POST for all the resources. In some cases there might even be GET verb and a mixture of both. Hence we are not really defining what each resource is doing. Level 2 addresses this issue by using HTTP verb to provide a notion on the kind of operation being applied by the resources. The 4 mainly used HTTP verbs are GET, POST, PUT and DELETE:


GET – Get an employee(s) defined by unique URI
PUT – Replace or create an employee
POST – Create a new employee
DELETE – delete an employee


Applying HTTP verb to our employee web services will result in the following:

Method on ServerURIHTTP Verb
CreateEmployee/ v1/employeePOSTInformation via WSDL
GetEmployee/ v1/employee/225GETInformation via WSDL
GetEmployeeTask/ v1/employee/225/tasksGETInformation via WSDL
SearchEmployee/ v1/employeeGETInformation via WSDL
UpdateEmployee/ v1/employee/225PUTInformation via WSDL
DeleteEmployee/ v1/employee/225DELETEInformation via WSDL


Level 3
To access a website on the internet, we are only required to remember its root URL. From this point, it is easy to navigate throughout the website to obtain the resources required. Level 3 brings the concept of discovering resources that can be carried out on a particular employee, providing a way for making the protocol more self-documenting. 

For e.g. a request to the resource SearchEmployee (/v1/employee – GET) might return the following result:


 
  
  
  
  
 
 
  
  
  
  
 


Each employee contains several link elements that define a list of resources available on the particular employee. The point of level 3 is to tell us what can be done next and which URI to access. The advantage of this is client application does not hard code URL on their side to perform operation but rather depend on the link element. On server side, the URL for the resource can be changed without any impact on the client.

Applying the 3 levels of the RMM, according to me, provide a means of defining a web service that is self-explanatory to all uniquely identified resources exposed and providing context to each resource defined.

Reference: Chapter 2 ASP.NET Web API 2, Building a REST Service from Start to Finish


Thursday, April 16, 2015

How to create a MS SQL Server alias for a database instance

Problem: On many developer machines, the name of the database server is different. It implies that the connection string section in web.config should be changed accordingly to the database server name on each developer machine, thus making the web.config file to be in a “modified” state in svn. This change cannot be committed as it will affect the connection string when the application is being run on other machine. Any changes made to the web.config (e.g. adding a new configuration key) will have to ensure that changes made to connection string are reverted back and then new change is committed.

Solution: Create a common alias name that point to the database server name on each developer machine and use the alias name in the web.config connection string section.
Steps (windows 7, SQL Server 2008 R2):

1. Open the Sql Server Configuration manager (Start Menu -> Microsoft SQL Server 2008 R2 -> Configuration Tool)

    a. Expand the Sql Server Network Configuration, select Protocols for and double click on the TCP/IP menu on the right pane:



    b. Change the value of Enabled to Yes. Note down the value of ListenAll (It will be either yes or no).

2. On the same popup, Go to the Ip Addresses tab and scroll to the IPAll section.



    a. If the value of ListenAll was yes – the port number MSSQL is using is the TCP Dynamic Ports

    b. If the value of ListenAll was no – the port number for this instance of MSSQL is the value of the TCP Dynamic Ports item for a specific IP address.

    c. Note that if the value of the TCP dynamic port was not set, you can restart the SQL Server Service and you will find the port specified on the same location

3. Expand the SQL Native Client 10.0 Configuration and right click on Aliases to create a new alias 



    a. Set the Alias Name property to the alias you want to use
    b. The Port No is the same port number we noted before in step 2
    c. The Server is the name of the MSSQL server instance of your machine,

4. Restart the MSSQL server service

5. Go to web.config and modify the connection string so that it is.


Saturday, August 23, 2014

Handle session object in ASP.NET MVC using model binder

One of the most commonly used methods to associate a user with a request is to use the ASP.NET session state feature. The Session object is accessible via the Session property. It uses a Key-Value pair to set and get values for a particular key, as follows:

1
2
Session["FirstName"] = "Ashish";
Session["BlogUrl"] = "http://boobun.blogspot.com";
Listing 1 - setting value to session

If we want to retrieve the value of a session key, it can be done as follows:

1
2
var firstName = Convert.ToString(Session["FirstName"]);
var blogUrl = Convert.ToString(Session["BlogUrl"]););
Listing 2 - accessing session object value 

We require access to an instance of HttpContext in order to make use of the Session object. It implies that codes using the session object will most likely go into our controller class's methods in ASP.NET MVC. The presence of setter and getter codes to access and set session values in our controller class is not an elegant way. Moreover, we will not be able to properly unit-test our controller method due to the presence of codes accessing the session object.

To counter this issue, we will make use of a custom model binder that allows us to encapsulate all codes related the session object in our Model Binder class. Consider the following code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
[HttpGet]
public ActionResult Home()
{
 if (!Convert.ToBoolean(Session["isUserLogged"]))
 {
  RedirectToAction("Login");
 }

 Session["LoginTime"] = DateTime.Now;

 return View();
}
Listing 3 - sample controller code using session object

As discussed earlier, the code in listing 3 cannot be properly unit tested. Hence, the next step is to define a class that will store all information we are using the session object for:

1
2
3
4
5
public class UserDetail
{
 public bool IsUserLoggedIn { get; set; }
 public DateTime LoginTime { get; set; }
}
Listing 4 - model class contain properties for which session is being used for

Create the model binder class that will relate the session object to our above defined class:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class UserDetailModelBinder : IModelBinder
{

 #region Constants

 private const string SessionKey = "User";

 #endregion


 #region Public Methods and Operators

 public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
 {
  UserDetail user = (controllerContext.HttpContext.Session != null) ? (controllerContext.HttpContext.Session[SessionKey] as UserDetail) : null;

  if (user == null)
  {
   user = new UserDetail();
   controllerContext.HttpContext.Session[SessionKey] = user;
  }

  return user;
 }

 #endregion
}
Listing 5 - model binder implementation for UserDetail class

The model binder class implement the IModelBinder interface and provide implementation of the BindModel method. Notice that we have access to the ControllerContext in the method which will allow us to handle session object.  The logic inside the BindModel is straightforward: we check if there exist an object in the session with the supplied key and return (by casting to UserDetail class) it if exist. Otherwise we create a new instance of UserDetail and assign it to the session with the same key. The method either return a new instance of UserDetail (if no session object exist for that user http request) or an already existing object in the session.

A last configuration required to notify ASP.NET MVC by using the UserDetailModelBinder class for creating instance of UserDetails should be included in the Global.assax, as follows:

1
ModelBinders.Binders.Add(typeof (UserDetail), new UserDetailModelBinder());
Listing 6 - Plug in together our custom model binder to be used by MVC

Refactoring the Home action method result in the following:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
[HttpGet]
public ActionResult Home(UserDetail user)
{
 if (!user.IsUserLoggedIn)
 {
  RedirectToAction("Login");
 }

 user.LoginTime = DateTime.Now;

 return View();
}
Listing 7 - Refactored code of listing 3 making use of binder class

When MVC obtain an http request to get the Home page, it analyses the list of parameters in the Get method and analyses the list of binders available. It tries to locate a binder which can create object of that type specified in our parameter list. In our case the type in our parameter is UserDetail and MVC will use the UserDetailModelBinder as the binder to create object of the type UserDetail (by virtue of the configuration we did in the Global.asax


The main benefits we achieved is that we removed all logic dealing with session codes from our controller and encapsulated it in the Model binder class. In turn this will allow us to properly unit test our controller method.