Article updated with video on REST.
Table of Contents
REST is nothing but using the current features of the “Web” in a simple and effective way. If you see, some of the amazing features of the Web are:
- 40 years old matured and widely accepted HTTP protocol.
- Standard and Unified methods like
POST
, GET
, PUT
and DELETE
. - Stateless nature of HTTP protocol.
- Easy to use URI (Uniform resource identifier) format to locate any web resource.
REST leverages these amazing features of the web with some constraints.
Let’s define REST in official words, REST is an architectural style built on certain principles using the current “Web” fundamentals.
There are 5 basic fundamentals of web which are leveraged to create REST services.
Internet is all about getting data. This data can be in a format of web page, image, video, file, etc. It can also be a dynamic output like get customers who are newly subscribed. The first important point in REST is start thinking in terms of resources rather than physical files.
Below are some examples of resources with URI:
So the first thing is, visualize everything as resource.
The old web identifies all resources by a URI. For instance, if you want to display customer with their orders, you can use www.questpond.com/DisplayCustomerandOrder.aspx. In REST, we add one more constraint to the current URI, every URI should uniquely represent every RESOURCE data.
For instance, you can see the below unique URI format for customer and orders fetched.
Customer data | URI |
Get Customer details with name “Shiv” | http://www.questpond.com/Customer/Shiv |
Get Customer details with name “Raju” | http://www.questpond.com/Customer/Raju |
Get orders placed by customer "Shiv" | http://www.questpond.com/Customer/Shiv/Orders |
Get orders placed by customer “Raju” | http://www.questpond.com/Customer/Raju/Orders |
Simplification is the way to success and that’s what exactly the goal of uniform interfaces is. When external clients are interacting with web resources, they expect simplified interfaces.
For instance, let’s say you have exposed customer and orders data / resource on the web. Let’s assume below are the methods / function names by which external clients can communicate to your application.
AddCustomer
InsertOrders
SelectCustomer
getOrders
DeleteCustomer
RemoveOrders
UpdateCustomers
Do the above method names look inconsistent and difficult to remember? Yes they do. Now what REST says is keep your interfaces uniform and simple. This can be achieved by using the uniform methods of HTTP protocol and combining the same with your resource operation.
Below is the list of HTTP methods for getting, creating, updating and deleting a resource on the web.
Methods | Description |
GET | Get a resource |
PUT | Create and Update a resource |
DELETE | Deletes a resource |
POST | Submits data the resource |
Now by combining the standard HTTP methods and your resource names, you can have uniform interfaces and thus leading to simplified communication. You can see from the below table how we have created uniform REST URL using standard HTTP methods.
Normal Method names | HTTP methods | REST Uniform URL |
AddCustomer | PUT | Customer/Shiv |
InsertOrders | PUT | Orders/1001 |
SelectCustomer | GET | Customer/Shiv |
getOrders | GET | Customer/Shiv/Orders |
DeleteCustomer | DELETE | Customer/Shiv |
RemoveOrders | DELETE | Customer/Shiv |
UpdateCustomers | PUT | Customer/Shiv |
When you send any request or you get any response, you are actually sending representations.
For example, let’s say you want to create a new customer
record, you would send some kind of representation as shown below using HTTP PUT
.
<Customer>
<Name>Questpond.com</Name>
<Address>Mulund Mumbai</Address>
</Customer>
Once the resource is created, you would get a representation as shown below. The below representation says the customer questpond has been successfully created and if you wish, you can use “http://www.questpond.com/Customer/Questpond/Orders” defined in the “Next” tag to create orders for the “questpond
” customer
.
<Customer>
<Name>Questpond.com</Name>
<Next>http://www.questpond.com/Customer/Questpond/Orders</Next>
</Customer>
The above representation was in XML format. If you wish, you can also send and receive other presentations like JSON. For instance, below is a simple JSON snippet for creating a new customer record with name and address.
{Customer :{ Name:'Questpond.com', Address:'Mulund Mumbai'}}
Every request should be an independent request so that we can scale up using load balancing techniques. Independent request means with the data also send the state of the request so that the server can carry forward the same from that level to the next level.
For instance, below are two simple representations, the first representation is sent for logging in.
<Login>
<Name>Questpond.com</Name>
<Password>sdkj#43445</Password>
</Login>
If you are logged in successfully you receive the below representation.
<Login>
<Success>true</Success>
</Login>
If you want to search for customer
, you would send him the below representation stating that you are in a state of successful logging in and would like to search all customer
s.
<Customer>
<Filter>All</Filter>
<Success>true</Success>
</Customer>
In other words, every request is independent and the server does not need to remember your previous request and states.
So summarizing REST leverages the old web HTTP by applying principles 5 important principles:
- Everything is a resource.
- Every resource is identified by a unique identifier.
- Use simple and uniform interfaces.
- Communication are done by representation.
- Be Stateless.
Enabling WCF REST services is a three step process:
- Enable HTTP bindings
- Expose methods via common interfaces
- Define your representation
In order to enable HTTP bindings, the first thing is to create an end point behavior with “webHttp
” binding. The “webHttp
” binding enables HTTP protocol on your WCF services.
<endpointBehaviors>
<behavior name="NewBehavior0">
<webHttp />
</behavior>
</endpointBehaviors>
Create a new endpoint
and bind the behavior with your endpoint
.
<services>
<service name="WcfRest.Service1">
<endpoint behaviorConfiguration="NewBehavior0" binding="webHttpBinding"
bindingConfiguration="" contract="WcfRest.IService1" />
</service>
</services>
In order to make your interfaces uniform, you can use the “UriTemplate
” property as shown in the below figure. You can see from the below code snippet how “getStudents
” can now be called by using a http GET request on “/Students/123
”, where 123
is the id of the student.
[OperationContract][WebGet(UriTemplate = "/Students/{id}")]string getStudents(string id);
In the same way, in the below code snippet, we are calling “AddStudent
” method using HTTP POST
and we have made the interface uniform using the “UriTemplate
” property as shown in the below code snippet.
[OperationContract]WebInvoke(Method = "POST",
UriTemplate = "/Students/{studentname}")]bool Addstudent(string studentName);
So now, if you want to get a particular student use http://localhost:27683/Students.svc/Students/1 with HTTP GET
method and if you want to add a new student call http://localhost:27683/Students.svc/Students/Shiv with HTTP POST
. Isn’t that much simpler as compared to “getStudents
” and “AddStudent
” methods.
[ServiceContract]
public interface IStudents
{
[OperationContract]
[WebGet(UriTemplate = "/Students/{id}")]
string getStudents(string id);
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/Students/{studentname}")]
bool Addstudent(string studentName);
}
Below is the implemented code for the above interface. We have created a collection of student
names in a string
collection. In order to add new students, we can call “AddStudent
” and to retrieve students, we can call “getStudents
”.
public class Students : IStudents
{
List<string> ostudents = new List<string>();
public Students()
{
ostudents.Add("Shivprasad");
ostudents.Add("Raju");
}
public string getStudents(string id)
{
return ostudents[0];
}
public bool Addstudent(string StudentName)
{
ostudents.Add(StudentName);
return true;
}
}
To get a particular student
, we need to invoke “getStudents
” by using HTTP GET
on the URL http://localhost:27683/Students.svc/Students/1 . The “1
” indicates that we want to retrieve the student with ID “1
”.
To add a particular student, we need to invoke “Addstudent
“ by using HTTP POST on the URL http://localhost:27683/Students.svc/Students/Shiv. “Shiv
” is the student name we wish to add to the collection.
In order to make a post and get on the above URLs, we will use simple HTML to do the same. You can also use other methods like “xmlhttprequest
”, WCF proxy, etc. In order to keep it simple in this article, we will use simple HTML for now.
<form action="http://localhost:27683/Students.svc/Students/1" method="get">
<input type="submit" />
</form>
So if you run the above HTML with the action pointing to the URL http://localhost:27683/Students.svc/Students/1 and using the “get
” method, you should get the below output.
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">Shivprasad</string>
In the same way, if you run the below HTML with the action pointing to the URL (http://localhost:27683/Students.svc/Students/shiv) and using the “post
” method, you should get the below output.
<form action="http://localhost:27683/Students.svc/Students/shiv" method="post">
<input type="submit" />
</form>
This XML file does not appear to have any style information associated with it. The document tree is shown below:
<boolean xmlns="http://schemas.microsoft.com/2003/10/Serialization/">true</boolean>
In the same way, you can try for other HTTP methods like PUT
, DELETE
, etc.
When we discussed REST fundamentals, we said one of the most important things is representation and format of representation. The current WCF [WebGet]
and [WebInvoke]
attributes help you to configure formats in both request and response in XML and JSON format.
In the below code snippet, we have created the Responseformat
as JSON.
[OperationContract] [WebGet(ResponseFormat=WebMessageFormat.Json,
UriTemplate = "/Students/{id}?format=json")]string getStudentsJSON(string id);
If you do a get on the URL you should get the value as shown in the below figure: -
If you are not clear with the above concepts explained, see our video on REST: -
For further reading do watch the below interview preparation videos and step by step video series.