Chapter 4. Building Web Services with ReST

In This Chapter

  • Understanding the principles of ReST

  • Implementing ReST services using WCF

  • Consuming ReST services

Chapter 3 includes a sidebar, "Using Different Endpoints," that has a big list of binding formats you can use with WCF. I point out that for most applications, you use SOAP, or binary. That's not necessarily accurate.

Another binding is pretty popular — it is the binding that your Web browser uses to get pages from Web servers. It is called ReST, and it stands for Representational State Transfer.

In this chapter, I introduce you to ReST and guide you through its advantages and drawbacks.

Getting to Know ReST

ReST is basically the use of the traditional GET and POST patterns the old folks will remember from CGI. For you young pups, it is the basic format of Web requests. For instance, when you click on a link that looks like this:

http://mydomain.com/start.aspx?id=3

. . . you are using ReST. Remember, we aren't talking about an implementation here. We are talking about a remote procedure call mechanism. It is just a way to get parameters for a query to a remote machine and to get data back.

We also aren't talking about a protocol, like SOAP is. ReST is an architecture. It has guidelines, not rules.

A ReST interface has four goals. They are

  • Scalability of component interactions

  • Generality of interfaces

  • Independent deployment of components

  • Intermediary components to reduce latency, enforce security, and encapsulate legacy systems

Use of ReST with WCF meets most but not all of those goals. Let's take a quick ride over the details of the implementation of ReST in WCF, and you can make your own call.

Understanding the Guiding Principles of ReST

There are four guiding principles to ReST. According to the standard, all ReSTful interfaces must provide interfaces that adhere to these principles. In the real world, compliance is up for discussion. Here are the principles:

  • Note

    Identification of resources: Individual resources (like a data item, for instance) are identified in requests (for example, using URIs in Web-based ReST systems). The resources themselves are conceptually separate from the representations that are returned to the client. For example, the server does not send its database, but rather, perhaps, some HTML, XML, or JSON that represents some database records expressed, for instance, in French and encoded in UTF-8, depending on the details of the request and the server implementation.

  • Manipulation of resources through these representations: When a client holds a representation of a resource, including any metadata attached, it has enough information to modify or delete the resource on the server, provided it has permission to do so.

  • Self-descriptive messages: Each message includes enough information to describe how to process the message (for example, which parser to invoke). An example of this is the use of Internet media types, previously known as MIME types. From the media type alone, the client must know how to process its contents. If it needs to look inside the message's contents in order to understand it, the message is not self-descriptive. For example, merely using the "application/xml" media type is not sufficient for knowing what to do with its contents, unless code-download is used.

  • Hypermedia as the engine of application state: If it is likely that the client will want to access related resources, these should be identified in the representation returned (for example, by providing their URIs in sufficient context, such as hypertext links). This creates an environment where the software system consuming the service has more than normal knowledge of the way the data is stored.

Diving into the details of ReST

ReST as a concept is as old as the Web, but as a Web service implementation it is fairly new — about as new as SOAP. The largest implementation of ReST as a standard is the Web itself. CGI is based on the ReST interface.

The call to a ReST interface is clearly smaller than a SOAP call. Seriously. Look at these two examples:

ReST:

POST /Start.asmx HTTP/1.1
Host: localhost
Content-Type: http; charset=utf-8
http://mydomain.com/start.aspx?id=3

SOAP:

POST /Service1.asmx HTTP/1.1
Host: localhost
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-
   instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
   xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <soap12:Body>
    <HelloWorld xmlns="http://tempuri.org/" />
  </soap12:Body>
</soap12:Envelope>

The XML of SOAP kinda gets in the way.

On the other hand. SOAP has a list of security features. There is a list of transaction features. There is a list of attachment features. SOAP has a lot of features.

ReST, not so much. ReST has only four features:

  • GET – Request a resource

  • PUT – Upload a resource

  • POST – Submit data

  • DELETE – Delete resource

Changing a WCF Service to Use ReST

Looking at the WCF service that is built in Chapter 3, it seems that changing the endpoints will solve the problem. This example starts with some of the code created in Chapter 3. Then we will alter the endpoint behavior manually to create a ReST service.

Getting the WCF service

Let's start by getting the code from the WCF service in Chapter 3 and tweaking it. Just follow these steps:

  1. Create a new WCF service application.

    I called mind SharpRest.

  2. Make a new Registration service by right-clicking the folder and choosing Add a New Service File.

  3. Copy the code into registration.svc and iRegistration.cs from the similarly named files in the Chapter 3 project.

  4. Add the Conference class and the iConference interface from Chapter 3.

Exposing the ReST service

Now for the editing. The class attributes you add here are important because they affect how the compiler sets up the service responses.

To implement ReST on the service side, there have to be three (Three!!! That's a bunch!) additional attributes on that service contract:

  • ServiceContractAttribute: Defines the interface as a service interface.

  • WebInvokeAttribute: Tells the compiler that this class can be called by a Web-based ReST model.

  • WebGetAttributeClass: Remember GET, PUT, POST, and DELETE? This tells the runtime that the class will respond to a GET.

All right, ServiceContract we got — it came with the template. We need to add the method contract. The interface now looks like this:

namespace SharpRest
{
    [ServiceContract]
    public interface IRegistration
    {
        [OperationContract]
        [WebInvokeAttribute]
        [WebGetAttribute]
List<Conference> conferencesAtLocation(int
       locationld);
        }
}

What does that do for us? It tells the runtime compiler that a URI can call this directly. You can check out the binding itself by looking at the test client, as shown in Figure 4-1.

A ReST binding.

Figure 4-1. A ReST binding.

That isn't all there is to it, though. We need to create a WebServiceHost.

Returning data in different ways

The WebServiceHost is a ServiceHost class that happens to handle ReST very well, so we use it for that purpose. There are a few ways to do this, just like there are in WCF. These include the following:

  1. Any .NET application running on a box can be a host. A Windows service, console application, even a running WPF application can host a service. As long as it has access to the network device, it should work.

  2. IIS can host the application, and you can configure it in code. This involves using a WebServiceHost object in the service codebehind, and decorating the class with attributes for configuration.

  3. The Web.config file can be set up to define an endpoint: This is the easiest way, and the way we do it in Chapter 3. If configured this way, adding other endpoints to the code is a straightforward change.

There isn't a binding in the WCF Configuration tool for the ReST binding, however, so we have to do it another way. Just follow these steps:

  1. Open the Web.Config for the service.

    There should be binding information in there from the SOAP service we built in Chapter 3. Leave that there.

  2. Add the bold listing for the custom POX binding under theServiceModel section.

    It is the first bold code in Listing 4-1.

  3. Add the Service information into the Service section. It is the secondbold code in Listing 4-1.

Example 4-1. The ReST Service Implementation

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0">
      <assemblies>
        <add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, Publ
    icKeyToken=b77a5c561934e089" />
      </assemblies>
    </compilation>
  </system.web>
  <system.serviceModel>
    <bindings>
      <customBinding>
        <binding name="poxBinding">
          <textMessageEncoding messageVersion="None" />
          <httpTransport />
        </binding>
      </customBinding>
     </bindings>
     <services>
        <service name="SHARPService.Registration">
          <clear />
          <endpoint address="http://localhost" binding="basicHttpBinding"
            name="SharpHttp" contract="SHARPService.IRegistration"
      listenUriMode="Explicit">
            <identity>
              <certificateReference storeName="My" storeLocation="LocalMachine"
                x509FindType="FindBySubjectDistinguishedName" />
            </identity>
            </endpoint>
            <endpoint address="http://localhost" binding="wsDualHttpBinding"
              bindingConfiguration="" name="SharpDual" contract="SHARPService.
         IRegistration" />
           </service>
           <service name="SHARPService.Registration">
             <host>
               <baseAddresses>
                  <add baseAddress="http://localhost" />
                </baseAddresses>
              </host>
<endpoint address="registration"
                binding="customBinding"
                bindingConfiguration="poxBinding"
              contract="SHARPService.IRegistration" />
   </service>
 </services>
 <behaviors>
   <serviceBehaviors>
     <behavior>
       <!-- To avoid disclosing metadata information, set the value below to
 false and remove the metadata endpoint above before deployment -->
       <serviceMetadata httpGetEnabled="true" />
       <!-- To receive exception details in faults for debugging purposes, set
 the value below to true. Set to false before deployment to avoid disclosing
 exception information -->
       <serviceDebug includeExceptionDetailInFaults="false" />
     </behavior>
   </serviceBehaviors>
 </behaviors>
</system.serviceModel>
<system.webServer>
  <modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
<connectionStrings>
  <add name="ConferenceDbEntities" connectionString="metadata=res://*/
   Sharp.csdl|res://*/Sharp.ssdl|res://*/Sharp.msl;provider=System.Data.
   SqlClient;provider connection string='Data Source=.SQLEXPRESS;AttachDbFil
   ename=&quot;C:Program FilesMicrosoft SQL ServerMSSQL10.SQLEXPRESSMSSQL
   DATAConferenceDb.mdf&quot;;Integrated Security=True;Connect Timeout=30;User
   Instance=True;MultipleActiveResultSets=True'" providerName="System.Data.
   EntityClient" />
 </connectionStrings>
</configuration>
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.250.153