What is REST?
REST = Representational State Transfer, is an architecture design to represent resources. REST provides a uniform interface through additional constraints around how to identify resources, how to manipulate resources through representations, and how to include metadata that makes messages self-describing. REST is not tied with any platform or technology, but Web is the only platform which satisfies all the constraints. So any thing you build using REST constraints, you do it on Web using HTTP. Following are the HTTP methods which are useful when creating REST Services.
HTTP Methods
- GET - Requests a specific representation of a resource
- PUT - Creates or update a resource with the supplied representation
- DELETE - Deletes the specified resource
- POST - Submits data to be processed by the identified resource
- HEAD - Similar to GET but only retrieves headers and not the body
- OPTIONS - Returns the methods supported by the identified resource
In this article, I am going to discuss how to design and consume a REST Web Service using the WCF Framework. As an example, I am going to create a REST service which creates, updates, and selects Employees. Follow the steps given below.
Designing the URI
To design REST services, you need to design a URI, so for that, you need to list out the resources that are going to be exposed by the service. As I am going to design an Employee create, update, and select service, the resource is the Employee.
Now to be more specific towards the operation:
- List Employees
- Select Employee by ID
- Create Employee
- Update Employee
- Delete Employee
For example, the service is hosted on a local IIS server and the URL to locate it is http://localhost/restservices/MyRestServices.svc. In the discussion below, I am going to design the URL presentation for each operation:
- List Employees
The URL to get the list of all employees: http://localhost/restservices/MyRestServices.svc/Employees.
But there are a number of Employees in the system and to apply a filter on the Employees, use: http://localhost/restservices/MyRestServices.svc/Employees?type = {type}.
Note: The above URL gets the list of employees of the type specified {type} in the URL.
To get a single Employee by using a unique ID of the Employee: http://localhost/restservices/MyRestServices.svc/Employees/{EmployeesID}.
Note: In the above URL, {EmployeesID} gets replaced by the ID of the Employee.
Extension to above scenario: If you want to get an employee by using an ID with a type: http://localhost/restservices/MyRestServices.svc/Employees/{EmployeesID}?type = {type}.
- Create Employee
The URL to create an Employee: http://localhost/restservices/MyRestServices.svc/Employees/{employeeid}
Note: In the above URL, {EmployeesID} gets replaced by the ID of the Employee.
- Update Employee
URL to update employee is http://localhost/restservices/MyRestServices.svc/Employees/{employeeid}.
Note: In the above URL, {EmployeesID} gets replaced by the ID of the Employee.
- Delete Employee
The URL to delete an employee is http://localhost/restservices/MyRestServices.svc/Employees/{EmployeeID}.
Note: In the above URL, {EmployeesID} gets replaced by the ID of the Employee.
As you can see, here the URL for Create, Update, and Delete are the same, but it makes a difference when you combine the URL with specific HTTP methods. Let's combine the URL(s) with the HTTP methods.
List employees
- GET - http://localhost/restservices/MyRestServices.svc/Employees
Create/Update employee
- PUT - http://localhost/restservices/MyRestServices.svc/Employees/{employeeid}
Note: Both Create/Update employee use the same URL, but you create an employee with employeeid =0, and you update an employee with empoloyeeid=anynumeircvalue or GUID. This URL can be different in your implementation.
Delete Employee
- DELETE - http://localhost/restservices/MyRestServices.svc/Employees/{EmployeeID}
Designing WCF with REST
Here is an article to get a better understanding about WCF services: Create, Host (Self Hosting, IIS hosting) and Consume WCF servcie. To design our REST WCF service, first start with the class to represent an Employee:
[DataContract]
public class Employee
{
[DataMember]
public string Employeename { get; set; }
[DataMember]
public string Designation { get; set; }
[DataMember]
public string Address { get; set; }
[DataMember]
public string Email { get; set; }
}
As you can see, the Employee
class has the DataContaract
attribute as it is going to serve data to the client, i.e., it will work as a data exchanger. Now start with the creation of the WCF service which is going to serve data to the client, i.e., going to work as the RESTfull service. You need to decorate each method in your service interface with the WebInvoke
attribute in addition to OperationContract
, which allows the user to bind a method with the UrlTemplate
and the HTTP method. Let's look at each method of the interface one by one.
public interface IService1
{
Get Methods
The following methods serve data which is requested using the GET method of HTTP.
GetEmployees
Allows to get all the employees. "tag
" allows the user to filter data because some times the system might contains a large number of employees which will increase traffic and slow down response, so by specifying tag=manager or tag=senior, you will get a specific set of employees.
[WebInvoke(Method = "POST",
ResponseFormat = WebMessageFormat.Json,UriTemplate = "?tag={tag}")]
[OperationContract]
Employees GetEmployees(string tag);
GetEmployee
Allows to get the employee with the specific ID. "Employee_id
" of the UriTemplate
gets replace with the employee ID.
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json,
UriTemplate = "Employees/{Employee_id}")]
[OperationContract]
Employee GetEmployee(string Employee_id);
Create and Update Method
The following method allows to insert new data and update existing data using the HTTP method PUT.
PutEmployeeAccount
This method allows to insert a new employee into a system and to update an existing employee. "Employee_Id
" of the UriTemplate
gets replaced by the employee ID if its is an update, and 0 if it's a new employee to be created.
[WebInvoke(Method = "PUT", ResponseFormat = WebMessageFormat.Json,
UriTemplate = "Employees/{Employee_Id}")]
[OperationContract]
string PutEmployeeAccount(Employee Employeeobj,string Employeename );
Delete Method
This method allows to remove data using the HTTP method DELETE.
DeleteEmployeeAccount
This method allows to delete an employee from the system. "Employee_Id
" of the UriTemplate
gets replaced by the employee ID.
[WebInvoke(Method = "DELETE", UriTemplate = "Employees/{Employee_Id}")]
[OperationContract]
void DeleteEmployeeAccount(string Employeename);
}
WebInvoke
WebInvokeAttribute
determines what HTTP method a service operation responds to, i.e., HTTP POST, GET, or DELETE.- Indicates a service operation is logically an invoke operation and that it can be called by the REST programming model.
UriTemplate
- A URI template is a URI-like string that contains variables marked in braces ({, }), which provides a consistent way for building and parsing URIs based on patterns.
- URI templates are composed of a path and a query. A path consists of a series of segments delimited by a slash (/). Each segment can have a literal value, and a variable value (written within curly braces [{ }]).The query part is optional. If present, it is the same as querystring name/value pairs. Elements of the query expression can be presented as (?x=2) or variable pairs (?x={val}).
- One of the reasons to add this class in .NET is to support the REST architectural style used by developers today.
Consume the WCF RESTfull service
Before you start, it's better to know how to configure and consume a WCF service using jQuery: Steps to Call a WCF Service using jQuery. Below is the jQuery code to consume a Web Service:
var Type;
var Url;
var Data;
var ContentType;
var DataType;
var ProcessData;
var method;
function CallService() {
$.ajax({
type: Type,
url: Url,
data: Data,
contentType: ContentType,
dataType: DataType,
processdata: ProcessData,
success: function(msg) {
ServiceSucceeded(msg);
},
error: ServiceFailed
});
}
function ServiceFailed(result) {
alert('Service call failed: ' +
result.status + '' + result.statusText);
Type = null;
Url = null;
Data = null;
ContentType = null;
DataType = null;
ProcessData = null;
}
The code above declares and initializes variables which are defined above to make a call to the service. The CallService
function sends a request to the service by setting data in $.ajax
.
GetEmployee
function GetEmployee() {
var uesrid = "1";
Type = "POST";
Url = "Service1.svc/Employees/1";
ContentType = "application/json; charset=utf-8";
DataType = "json"; ProcessData = false;
method = "GetEmployee";
CallService();
}
The GetEmployee
method is used to get an employee with a specific ID. The URL to make a call to the service is Service1.svc/Employees/1: in this, 1 is the employeeid. This function calls the RESTfull service function which has the URLTemplate Employees/{Employee_Id} and the method type is POST.
CreateEmployee
function CreateEmployee() {
Type = "PUT";
Url = "Service1.svc/Employees/0";
var msg2 = { "Employeename": "Denny",
"Designation": "engg.",
"Address": "vadodara",
"Email": "pr@ab.com" };
Data = JSON.stringify(msg2);
ContentType = "application/json; charset=utf-8";
DataType = "json";
ProcessData = true;
method = "CreateEmployee";
CallService();
}
This method is used to create an employee. The URL to make call to the service is Service1.svc/Employees/Denny. In this 0 is employeeID (0 because I am creating a new employee). This function calls the RESTfull service function which has the URL template Employees/{Employee_Id} and the method type is POST. In the createemployee
method, I am creating an Employee
object with the property required which is going to be consumed by the service to create the employee. The following code checks the result.GetUserResult
statement, so your result object gets the property: your service method name + result. Otherwise, it will give an error like object not found in JavaScript.
function ServiceSucceeded(result) {
if (DataType == "json") {
if(method == "CreateEmployee")
{
alert(result);
}
else
{
resultObject = result.GetEmployeeResult;
var string = result.Employeename + " \n " +
result.Designation + " \n " +
result.Address + " \n " + result.Email;
alert(string);
}
}
}
function ServiceFailed(xhr) {
alert(xhr.responseText);
if (xhr.responseText) {
var err = xhr.responseText;
if (err)
error(err);
else
error({ Message: "Unknown server error." })
}
return;
}
$(document).ready(
function() {
CreateEmployee();
}
);
In this article, I just showed the examples of CreateEmployee
and GetEmployee
because that is enough to understand how to consume a method of a WCF RESTfull service. Now you can create other methods by downloading the code and understanding it better.
Summary
It's quite easy to create a RESTfull service using the .NET WCF framework. But it requires an understanding of how to represent your resource. i.e., designing the URL template to represent your resources on the Web.