Representational State Transfer (REST) is an architecture style that is used for creating scalable services. A RESTful Web Service is one that conforms to the REST architecture constraints. The REST architectural style has quickly become very popular over the world for designing and architecting applications that can communicate. Due to its simplicity, it has gained widespread acceptance worldwide in lieu of the SOAP- and WSDL-based Web Services. It is essentially a client-server architecture and uses the stateless HTTP protocol. In this book, we will cover REST using the HTTP protocol. Our journey towards mastering REST and Web API has just begun!
In this chapter, we will cover the following topics:
What is REST? Why is it becoming so popular over time? Is REST an alternative to Web Services? How can I make use of the .NET Framework to implement RESTful services? We will answer these questions as we progress through the sections of this chapter.
REST is an architectural style for designing distributed applications that can intercommunicate. Note that REST is not a technology or a set of standards. Rather, it is a set of constraints that can be used to define a new style of architecture. Essentially, it is a client-server architectural style where the connections are stateless.
REST is not a standard; rather, it is an architectural alternative to RPC and Web Services. In the REST architectural style, you can communicate among systems using the HTTP protocol (if HTTP is the protocol in use). Actually, the World Wide Web (WWW) can be viewed as a REST-based architecture. A RESTful architecture is based on a cacheable and stateless communication protocol.
REST is an architectural style that divides an application's state and functionality into resources. These resources are in turn addressable using URIs over HTTP. These resources have a common interface and are uniquely addressable. A REST-based model is stateless, client-server-based, and cacheable.
As discussed, in a REST-based model, resources are used to represent state and functionality. Resources are identified through logical URLs. In a typical REST-based model, the client and the server communicate using requests and responses. The client sends a request to the server for a resource and the server in turn sends the response back to the client.
The main design goals of the REST architectural style include:
The basic difference between SOAP and REST is that while the former emphasizes verbs, the latter emphasizes resources. In REST, you define resources, and then use a uniform interface to operate on them using the HTTP verbs. It should also be noted that REST is simpler to use, because it heavily leverages the HTTP transport mechanism for formatting, caching, routing, and operations performed on the given resources. On the contrary, with SOAP, there are no such conventions. A SOAP-based service can easily be exposed via TCP/IP, UDP, SMTP, or any other transport protocol. So, it doesn't have to be dependent on the HTTP protocol.
In a REST-based model, a request is comprised of an endpoint URL, a developer ID, parameters, and the desired action. The endpoint URL is used to represent the complete address. The developer ID is a key which uniquely identifies each request origin. The desired action is used to denote the action to be performed.
The REST architecture makes use of some common HTTP methods for CRUD (Create, Read, Update, and Delete) operations. These are as follows:
GET
: This is used to request for a specific representation of a resource.HEAD
: This is used to retrieve the resource headers only.PUT
: This is used to update a resource.DELETE
: This is used to delete the specified resource.POST
: This is used to submit data that is to be processed by the identified resource. Ideally, POST
should be used for only creating resources, while PUT
is used for only updating them.The resource concept is one of the most important ones in REST. A few examples of public implementations of REST include the following:
A resource is identified using a URI. In the REST style of architecture, communication between a server and a client takes place using requests and responses. The client (also known as the consumer) requests for a resource from the server. The server then sends the response back to the client.
In the REST architectural paradigm, resources are used to represent the state and functionality of the resources. They are identified by using logical URIs so that they can be universally addressable. The REST architecture is essentially based on HTTP—a stateless protocol. However , resources can be cached as and when required. Note that since HTTP provides cache mechanism, REST implemented on top of the HTTP protocol provides the features and benefits of HTTP. Also, you can set cache expiration policies for the cached data.
Any REST request comprises of the following components:
Let's take an example. The following link is a typical REST request URL: http://localhost/payroll?devkey=1&action=search&type=department&keyword=DepartmentID.
In the previous request, the endpoint is http://localhost/payroll
, the desired action is search
and the developer key is 1
. You also have the type
and keyword
parameters provided in the request. Please refer to the following code snippet, which shows how a REST request and response looks like:
<?xml version="1.0" encoding=" UTF-8"?> <Request> <RequestId>1R3ABC</RequestId> <Parameters> <Argument Name="devkey" Value="1" /> <Argument Name="action" Value="search" /> <Argument Name="type" Value="department" /> <Argument Name="keyword" Value="phone" /> </Parameters> </Request> <Response> <ResultCount>2</ResultCount> <Record> <FirstName>Joe</FirstName> <LastName>Stagner</LastName> <DepartmentID>1</DepartmentID> </Record> <Record> <FirstName>Stephen</FirstName> <LastName>Smith</LastName> <DepartmentID>1</DepartmentID> </Record> </Response>
The REST architectural paradigm defines the following constraints to the architecture:
A RESTful implementation is based on a client-server model. The servers and the clients are clearly isolated. This implies that the servers and clients can be modified independently. The server is not at all concerned with the user interface. Similarly, the user interface is not concerned about how data is persisted.
The REST architecture is based on the stateless HTTP protocol. In a RESTful architecture, the server responses can be cached by the clients. Any request from the client to the server should have enough information so that the request can be understood and serviced, but no client context would be stored in the server. This type of design ensures that the servers are more visible for performance monitoring and are scalable.
In a typical REST architecture, the clients should be able to cache data. To manage cache better, the architecture allows us to set whether a response can be cached or not. This feature improves scalability and performance.
The servers in a REST architecture can (if needed) extend or customize the functionality of a particular client. This is known as "code on demand"; this feature allows the servers in a REST architecture implementation to transfer logic to the clients if such a need arises.
The REST architectural style defines a uniform interface between the clients and the servers; therefore, it allows only a limited set of operations that are defined using the standard HTTP verbs, such as, GET
, PUT
, POST
, and DELETE
.
Simple Object Access Protocol (SOAP) is a simple, light weight, stateless, XML-based protocol that can be used for exchangeing data between heterogeneous systems in a distributed environment. SOAP can be used to transfer data, irrespective of the platform and language in use. A typical SOAP message format is as follows:
<SOAP: Envelope> <SOAP: Header> </SOAP: Header> <SOAP: Body> </SOAP: Body> </SOAP: Envelope>
The following code is an example of a SOAP request:
<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <soapenv:Header> <ns1:RequestHeader soapenv:actor="http://schemas.xmlsoap.org/soap/actor/next"soapenv:mustUnderstand="0"xmlns:ns1="https://www.example.com/getData/P007"> <ns1:authentication xsi:type="ns1:ClientLogin" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><ns1:token>SuchALongToken</ns1:token> </ns1:authentication> <ns1:networkCode>ABC-XYZ-0012345</ns1:networkCode> <ns1:applicationName>Sample</ns1:applicationName> </ns1:RequestHeader> </soapenv:Header> <soapenv:Body> <getProductData xmlns="https://www.example.com/getData/P007"> <filterData> <query>WHERE productId IS NOT NULL</query> </filterData> </getProductData> </soapenv:Body> </soapenv:Envelope>
The following code snippet illustrates the SOAP response for the previous request:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Header> <ResponseHeader xmlns="https://www.example.com/getData/P007"> <requestId>Some Request Id</requestId> <responseTime>26</responseTime> </ResponseHeader> </soap:Header> <soap:Body> <getProductDataResponse xmlns="https://www.example.com/getData/P007"> <rval> <totalResultSetSize>1</totalResultSetSize> <startIndex>0</startIndex> <results> <productId>7</productId> <productName>CTV</productName> <description>Samsung LED Color Television</description> <status>Active</status> <productCode>P007</productCode> </results> </rval> </getProductDataResponse> </soap:Body> </soap:Envelope>
Note that SOAP can be used without the HTTP protocol, and SOAP always uses the POST
operation. SOAP makes use of XML and the stateless HTTP protocol (if used with HTTP) to access services. A typical SOAP request looks like the following code:
GET /price HTTP/1.1 Host: http://localhost <?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" xmlns:m="http://localhost/product"> <soap:Header> <m:DeveloperKey>1</t> </soap:Header> <soap:Body> <m:GetProductPrice> <m:ProductCode>P001</m:ProductCode> </m:GetProductPrice> </soap:Body> </soap:Envelope>
In reference to the previous code snippet, the Body
section of the SOAP request contains the actual XML request object that is sent. The following code snippet illustrates a typical SOAP response:
HTTP/1.1 200 OK <?xml version="1.0"?> <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" xmlns:m="http://localhost/product"> <soap:Body> <m:GetProductPriceResponse> <m:Price>1008.78</m:Price> </m:GetProductPriceResponse> </soap:Body> </soap:Envelope>
REST is an architectural paradigm that is used to model how data is represented, accessed, and modified on the Web. REST uses the stateless HTTP protocol and the standard HTTP operations (GET
, PUT
, POST
, and DELETE
) to perform CRUD operations. REST allows you to do all that you can do with SOAP and XML-RPC. Along with that, you can use firewalls for security and also use caching for enhanced performance. The REST counterpart for the same request is simple, and is shown as follows:
GET /product?ProductCode=P001 HTTP/1.1 Host: http://localhost
The REST response to the previous request would be as simple. It is shown in the following code snippet:
HTTP/1.1 200 OK <?xml version="1.0"?><m:Price xmlns:m="http://localhost/product">1008.78</m:Price>
XML-RPC is a XML-based remote procedure calling protocol. The following code snippet is an example of a typical XML-RPC POST request:
POST /product HTTP/1.1 Host: http://localhost <?xml version="1.0"?> <methodCall> <methodName>product.GetProductPrice</methodName> <params> <param> <value><string>P001</string></value> </param> </params> </methodCall>
In response to the previous XML-RPC request, the following code snippet is how a typical XML-RPC response would look:
HTTP/1.1 200 OK <?xml version="1.0"?> <methodCall> <methodName>product.GetProductPrice</methodName> <params> <param> <value><double>1008.78</double></value> </param> </params> </methodCall>
Windows Communication Foundation (WCF) is a Microsoft framework that provides a unification of distributing technologies (Web Services, Remoting, COM+, and so on) under a single umbrella. The WCF Framework was first introduced in 2006 as part of the .NET Framework 3.0. It is a framework comprised of a number of technologies to provide a platform for designing applications that are based on SOA and have the capability to intercommunicate. According to Microsoft, at http://msdn.microsoft.com/en-us/library/bb907578.aspx,
Windows Communication Foundation (WCF) is a unified framework for creating secure, reliable, transacted, and interoperable distributed applications. In earlier versions of Visual Studio, there were several technologies that could be used for communicating between applications.
The three most important concepts related to the WCF architecture include services, clients, and messages. The following figure examines the building blocks of the WCF architecture.
The three most important concepts related to the WCF architecture are: services, clients, and messages. Contracts in the WCF can be of three types: service contract, data contract, and message contract.
WCF works on a contract-based approach. A WCF Service
class is one that implements at least one service contract. A service contract is an interface that is used to define the operations that are exposed by the WCF Service
class. A WCF Service
class is just like any other .NET class, except that it is marked with the ServiceContract
attribute. A message contract may be defined as a way that allows you to change the format of the messages. Note that the ServiceContract
, DataContract
, and other related attributes are defined in the System.ServiceModel
namespace. Binding in WCF is used to specify how a particular service would communicate with other services of its kind and/or with other clients (also known as consumers).
Also, any method that is preceded by the OperationContract
attribute is externally visible to the clients for SOAP-callable operations. If you have a method that doesn't have this attribute set, the method would not be included in the service contract, and so the WCF client would not be able to access that operation of the WCF service.
The following is a list of the pre-defined, built-in bindings in the WCF:
Endpoints in the WCF are used to associate a service contract with its address. Channels are actually a bridge between the service and its client. The following types of supported channels are available in the WCF:
Note that a WCF service is based on three concepts: address, binding, and contract. Also, a WCF service and a WCF client communicate using messages. The following figure examines how messages are used for communication in the WCF:
These messages can, in turn, have one of the following patterns:
WCF 4.5 comes with improved support for REST-based features. In this section we will first implement a simple WCF service, and then make the necessary changes to it make the service RESTful. The newer versions of the WCF provide improved support for REST-based features.
Now, let's take a closer look at the WCF REST attributes and their purposes. Incidentally, all these attributes are available in the System.ServiceModel.Web.dll
library. In this section, we will discuss the attributes of which we would frequently make use while working with RESTful services.
The usage of the WebServiceHost
attribute simplifies hosting of web-based services. It derives from the ServiceHost
class and overrides the OnOpening
method and automatically adds the WebHttpBehavior
class to the endpoint. The following code snippet illustrates how the WebServiceHost
attribute is used:
WebServiceHost host = new WebServiceHost(typeof(ClassName), baseAddress); WebHttpBinding binding = new WebHttpBinding(); host.AddServiceEndpoint(typeof(ISomeContract), binding, "WebServiceHost"); host.Open();
The WebHttpBinding
attribute produces an appropriate HTTP-based transport channel. Here, the security is handled by the WebHttpSecurity
class. Services can be exposed using the WebHttpBinding
binding by using either the WebGet
attribute or the WebInvoke
attribute.
The following code snippet illustrates how the webHttpBinding
attribute is used:
<configuration> <system.serviceModel> <services> <service name="PacktService"> <endpoint binding="webHttpBinding" contract="PacktService" behaviorConfiguration="webHttp"/> </service> </services> <behaviors> <endpointBehaviors> <behavior name="webHttp"> <webHttp/> </behavior> </endpointBehaviors> </behaviors> </system.serviceModel> <configuration>
The WebHttpBehavior
attribute customizes the HTTP-based dispatching logic, and it overrides operation selection, serialization, and invocation. The WebHttpBehavior
class in the System.ServiceModel.Description
namespace is shown as follows:
public class WebHttpBehavior : IEndpointBehavior { // Properties public virtual bool AutomaticFormatSelectionEnabled { get; set; } public virtual WebMessageBodyStyle DefaultBodyStyle { get; set; } public virtual WebMessageFormat DefaultOutgoingRequestFormat { get; set; } public virtual WebMessageFormat DefaultOutgoingResponseFormat { get; set; } public virtual bool FaultExceptionEnabled { get; set; } public virtual bool HelpEnabled { get; set; } protected internal string JavascriptCallbackParameterName { get; set; } // Methods public virtual void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters); protected virtual void AddClientErrorInspector(ServiceEndpoint endpoint, ClientRuntime clientRuntime); protected virtual void AddServerErrorHandlers(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher); public virtual void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime); public virtual void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher); protected virtual WebHttpDispatchOperationSelector GetOperationSelector(ServiceEndpoint endpoint); protected virtual QueryStringConverter GetQueryStringConverter(OperationDescription operationDescription); protected virtual IClientMessageFormatter GetReplyClientFormatter(OperationDescription operationDescription, ServiceEndpoint endpoint); protected virtual IDispatchMessageFormatter GetReplyDispatchFormatter(OperationDescription operationDescription, ServiceEndpoint endpoint); protected virtual IClientMessageFormatter GetRequestClientFormatter(OperationDescription operationDescription, ServiceEndpoint endpoint); protected virtual IDispatchMessageFormatter GetRequestDispatchFormatter(OperationDescription operationDescription, ServiceEndpoint endpoint); public virtual void Validate(ServiceEndpoint endpoint); protected virtual void ValidateBinding(ServiceEndpoint endpoint); }
The WebOperationContext
attribute is used to access the HTTP specifics within methods. You can retrieve the current context using the WebOperationContext.Current
property. It provides properties for incoming/outgoing request/response context.
The following code snippet illustrates how to get the HTTP status code:
HttpStatusCode status = WebOperationContext.Current.IncomingResponse.StatusCode;
This attribute is used to control the message format in your services.
You can control the format of your messages using the RequestFormat
and ResponseFormat
properties, as shown in the following code:
[OperationContract] [WebGet(ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)] public Employee GetData() { return new Employee { Firstname = "Joydip", Lastname = "Kanjilal", Email = "[email protected]"; }; }
The WebGet
attribute exposes operations using the GET
verb. In other words, the WebGet
attribute is used to map the incoming HTTP GET
requests to particular WCF operations by using URI mapping. How this attribute is defined in the System.ServiceModel.Web
namespace is shown in the following code snippet:
[AttributeUsageAttribute(AttributeTargets.Method)] public sealed class WebGetAttribute : Attribute, IOperationBehavior
An example that illustrates how you can use the WebGet
attribute is shown as follows:
[OperationContract] [WebGet(UriTemplate="/employee/{id}")] public Employee GetEmployee(int id) { Employee empObj = null; // Get employee object from the database return empObj; }
The WebInvoke
attribute exposes services that use other HTTP verbs, such as POST
, PUT
, and DELETE
. In other words, the WebInvoke
attribute is used for all the other HTTP verbs other than the GET
requests. The following code snippet shows how this attribute is defined in the System.ServiceModel.Web
namespace:
[AttributeUsageAttribute(AttributeTargets.Method)] public sealed class WebInvokeAttribute : Attribute, IOperationBehavior Here is an example that illustrates the usage of the WebInvoke attribute: [OperationContract] [WebInvoke(Method = "DELETE", UriTemplate = "/employee/{id}")] public void DeleteEmployee(int id) { // Code to delete an employee record in the database }
The UriTemplate
class belongs to System.UriTemplate
and implements the URI template syntax that enables you to specify variables in the URI space. UriTemplate
is a class that represents a URI template. UriTemplate
is a URI string that contains variables enclosed by braces ({
, }
). Note that the UriTemplate
property is specified on the WebGet
and WebInvoke
attributes that we used earlier to identify an employee resource.
The following code snippet illustrates how UriTemplate
is used:
[WebGet(UriTemplate = "RetrieveUserDetails/{userCode}/{projectCode}")] public string RetrieveUserDetails(string userCode, string projectCode) { }
The following table lists the important HTTP methods and their uses:
Method |
Description |
---|---|
|
This is used to request for a representation of a specific resource |
|
This is used to create or update a resource with a specific representation |
|
This is used to delete a specific resource |
|
This is used to submit data that is to be processed by a particular resource |
|
This is similar to GET, but it retrieves only the headers |
The HTTP protocol also defines a list of standard status codes that are used to specify the result of processing of a particular request. The following table lists the standard HTTP status codes and their uses:
Status Code |
Description |
---|---|
100 |
Informational |
200 |
Successful |
201 |
Created |
202 |
Accepted |
300 |
Redirection |
304 |
Not modified |
400 |
Client error |
402 |
Payment required |
404 |
Not found |
405 |
Method not allowed |
500 |
Server error |
501 |
Not implemented |
A RESTful web service (or the RESTful Web API) is a service that comprises a collection of resources. These resources include a base URI that is used to access the web service, a MIME type (that is, JSON, XML, and so on), and a set of defined operations (that is, POST
, GET
, PUT
, or DELETE
). A RESTful service is platform and language neutral. However, unlike a Web Service, there isn't any official standard set for RESTful services. REST is just an architectural style; it is devoid of any standards as such. The basic advantages of using REST are transport neutrality and the facility to use advanced WS-*
protocols. REST is interoperable, simple to use, and has a uniform interface.
RESTful web services are services that are based on the REST architectural paradigm. Essentially, these (also known as a RESTful Web API) are web services that are comprised of a collection of resources. These resources are given as follows:
POST
, GET
, PUT
, or DELETE
Similar to web services, a REST service is platform and language independent, based on HTTP, and can be used even with firewalls. Note that unlike web services that are based on the SOAP protocol, there is no official standard for RESTful services. REST is simply an architectural style that doesn't have any set standards. The following code snippet illustrates an example of a SOAP request:
<?xml version = "1.0"?> <soap:Envelope> xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding"> <soap:body emp="http://localhost/payroll"> <emp:GetEmployeeDetails> <emp:EmployeeID>1</emp:EmployeeID> </emp:GetEmployeeDetails> </soap:Body> </soap:Envelope>
The following URLshows how the same can be represented using REST:
http://localhost/payroll/EmployeeDetails/1
The RESTful web services map the HTTP methods to the corresponding CRUD operations. The previous two tables show how these are mapped: