Category Archives: REST

RESTful Web Services for Resource-Oriented Architectures (ROA) – Part 4 – Statelessness

The second constraint Dr. Fielding places on RESTful architectures is that of Statelessness. In a RESTful web service, “communication must be stateless in nature … such that each request from client to server must contain all of the information necessary to understand the request, and cannot take advantage of any stored context on the server. Session state is therefore kept entirely on the client.” 1

In a Resource Oriented Architecture, Richardson and Ruby define two types of state: application (or session) state which is the responsibility of the client and resource state which is held on the server.2 To illustrate the difference in the two types of state, consider the banking service found in our previous post RESTful Web Services for Resource-Oriented Architectures (ROA) – Part 2 – HATEOAS. Pending transactions are not kept in a session controlled by the server. The server does not wait for and is not expecting the client to proceed through the completion of the posting process in any particular order or timeline. Instead, pending transaction are resources stored on the server. It is up to the client to retrieve the transactions and then decide whether to post, edit or delete them. The client determines the next step he wants to take and when he will take it. The server responds with an appropriate answer – in the form of another resource – to the client’s requests. If the client tries to POST, PUT or DELETE an invalid resource, the server simply returns another resource indicating failure and containing links that can lead the client to a remedy.

Suppose our banking service returns the following resource when a client makes a GET request to “/bank/transferforms/dlwelch”. The response contains a list of all pending and posted transfer transactions for account dlwelch.

200 OK
Allow: GET, POST
Content-Type: application/xml; charset=utf-8
Location: "/bank/transferforms/dlwelch"

  <transferforms>
    <pendingforms>
      <form> 
        <id>1235</id>
        <link rel="self"  type="application/xml"
              uri="/bank/transferforms/dlwelch/pending/1235" />
      </form>
      <link rel="self"  type="application/xml"
            uri="/bank/transferforms/dlwelch/pending" />
    </pendingforms>
    <postedforms>
      <form> 
        <id>0001</id>
        <link rel="self"  type="application/xml"
              uri="/bank/transferforms/dlwelch/posted/0001" />
      </form>
      ...
      <form> 
        <id>1234</id>
        <link rel="self"  type="application/xml"
              uri="/bank/transferforms/dlwelch/posted/1234" />
      </form>
      <link rel="self"  type="application/xml"
            uri="/bank/transferforms/dlwelch/posted" />
    </postedforms>
    <link rel="self" type="application/xml" 
          uri="/bank/transferforms/dlwelch" />
    <link rel="up" type="application/xml" 
          uri="/bank/accounts/dlwelch" />
    <link rel="/bank/rel/home" type="application/xml" 
          uri="/bank" />
    <link rel="/bank/rel/create" type="application/xml" 
          uri="/bank/transferforms/dlwelch" />
  </transferforms>

As described in our previous article, the client can finish a pending transaction by submitting a POST request to the pending transaction’s URL. But if we tried to POST to “/bank/transferforms/dlwelch/pending/1234”, our banking service should return an error response, for example:

410 GONE
Content-Type: application/xml; charset=utf-8
Location: "/bank/transferforms/dlwelch/pending/1234"

<error>
  <link rel="/bank/rel/transfers" type="application/xml" 
       uri="/bank/transferforms/dlwelch" />
  <link rel="/bank/rel/accounts" type="application/xml" 
       uri="/bank/accounts/dlwelch" />
  <link rel="/bank/rel/customers/dlwelch/" type="application/xml" 
       uri="/bank/customers/dlwelch/" />
  <link rel="/bank/rel/home" type="application/xml" 
       uri="/bank" />
</error>

This response tells us the resource located at “/bank/transferforms/dlwelch/pending/1234” existed at one time but has been permanently moved or deleted.

All responses from a RESTful service – including error messages – are returned to the client as useful resource representations that guide the client to an acceptable state. A RESTful service, due to its stateless nature, never requires the client to be in a particular state in order to provide an appropriate, valid response to the client’s request. The service will not become confused or inoperable because the client does not follow a pre-defined process flow. And it will not re-post our transfer or re-submit an online payment – even when the user hits the back button.

“HTTP is an intrinsically stateless protocol, so when you write a web service you get statelessness by default. You have to do something to break it. The most common way to break statelessness is to use your framework’s version of HTTP sessions.” 2 Take, for example, ASP.NET session state. “ASP.NET session state enables you to store and retrieve values for a user as the user navigates ASP.NET pages in a Web application. HTTP is a stateless protocol. This means that a Web server treats each HTTP request for a page as an independent request. The server retains no knowledge of variable values that were used during previous requests. ASP.NET session state identifies requests from the same browser during a limited time window as a session, and provides a way to persist variable values for the duration of that session. By default, ASP.NET session state is enabled for all ASP.NET applications.” 5 ASP.NET purposely breaks the natural statelessness of HTTP. By retaining session identifiers and variables on the server, an ASP.NET web application can dictate the application state to the client. For an ASP.NET developer, the first thing to do when moving to a RESTful ROA is to abandon any ideas about sessions.

Instead of sessions and methods, start thinking about resources and representations. “A (RESTful) web service only needs to care about your application state when you’re actually making a request. The rest of the time it doesn’t even know you exist. This means that whenever a client makes a request, it must include all the application states the server will need to process the request.”2 If you get stuck trying to remove application state from the server, ask yourself how you would accomplish the same task using hard-copy documents. Our banking service works the same way as when we present a paper check at the bank teller window. We need to show a drivers license (authentication), a valid check made out to the bearer (authorization) and a deposit slip for our account (URI request). In return we will receive a deposit receipt or cash (resource representation) depending on the resource request we submitted.

The Jazz Artist web service discussed in previous posts is a stateless service. The client can make a request to any URI, in any order, without the server having knowledge of previous requests. The server considers each client request in isolation and then returns a RESTful response – even if the returned representation is an error report.

400 Bad Request
Date: Fri, 01 Nov 2013 19:27:21 GMT
Server: Microsoft-IIS/7.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Content-Type: application/xml; charset=utf-8
Location: http://dlwelchservices.com/jazz/badrequest?aspxerrorpath=/jazz/artists/125*
Cache-Control: no-cache
Content-Length: 503
<?xml version="1.0" encoding="utf-8"?>
<JazzArtists xmlns="http://schemas.dlwelch.com/JazzService" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Artists/>
<Links>
<link rel="/jazz/rel/home" href="http://dlwelchservices.com/jazz/artists" type="application/xml"/>
<link rel="/jazz/rel/search" href="http://dlwelchservices.com/jazz/artists/?firstname={firstname}&lastname={lastname}&grammys={grammys}" type="application/xml"/>
</Links>
</JazzArtists>

It is up to the client application to manage state and works it’s way through our service in a meaningful progression using the information provided by the response.


1. Fielding, Roy Thomas. Architectural Styles and the Design of Network-based Software Architectures. Doctoral dissertation, University of California, Irvine, 2000.

2. Richardson, Leonard and Ruby, Sam. RESTful Web Services. Sebastopol: O’Reilly Media, Inc., 2008. Ebook

3. Fielding, Roy Thomas. REST APIs must be hypertext-driven. Untangled – Musings of Roy T. Fielding, October 20, 2008

4. Fielding, Roy Thomas, et. al. RFC 2616 – Hypertext Transfer Protocol – HTTP/1.1. The Internet Society, June 1999

5. MSDN Library – ASP.NET Session State Overview – .Net 4

RESTful Web Services for Resource-Oriented Architectures (ROA) – Part 3 – The Uniform Interface

“The central feature that distinguishes the REST architectural style from other network-based styles is its emphasis on a uniform interface between components.”1 For a web service we use the HTTP protocol. And to create a RESTful a web service, we must use HTTP’s interface uniformly, i.e. the same way every service across the web uses HTTP as specified in the HTTP 1.1 standard.2 There can be no “changes to the communication protocols aside from filling-out or fixing the details of underspecified bits of standard protocols, such as HTTP’s PATCH method or Link header field.”3

In my previous posts on RESTful web services, we discussed the resource URIs and HATEOAS. Now we’ll consider how our service follows the Uniform Interface as provided by HTTP.

Our Jazz Web Service uses the standard HTTP verbs GET, PUT, POST and DELETE as defined by RFC 2616. A GET request is always safe and results in a representation of an existing resource being sent to the requester. PUT and DELETE are idempotent – meaning that regardless of the number of times an identical request is made, the result is the same. For example, if you send a DELETE request to jazz/artists/123 and then send it again jazz/artists/123 is still gone. Similarly, PUT is used to edit an existing resource. If you PUT identical information to an existing URI the outcome is the same as when you PUT the same data the first time. POST, on the other hand, is neither safe nor idempotent but is used to append a “new subordinate of the resource identified by the Request-URI”.4 Posting identical information will result in duplicate resources with multiple URIs.

Additionally, each verb’s action is identical – i.e. uniform – across all service URIs that accept the verb. A GET to any service URI results in the safe return of a resource representation. All URIs that accept a PUT do so to edit the resource by modifying the representation and putting it back to URI. Any URI that accepts a DELETE will be removed from the service whenever a delete command is sent to the URI. A POST is only accepted by the bookmark URI and results in new artists being appended to the resource.

We must also include standard HTTP response codes and headers. The Jazz Web Service response headers include a response code and text, a list of the allowed HTTP verbs for the URI, the response content type and the location. For example, if the resource still exists, a GET to http://dlwelchservices.com/jazz/artists/2 results in:

200 OK
Allow: GET, PUT, DELETE
Content-Type: application/xml; charset=utf-8
Location: http://dlwelchservices.com/jazz/artists/2
...
<?xml version="1.0" encoding="utf-8"?>
<JazzArtist xmlns="http://schemas.dlwelch.com/JazzService" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
 <Artist>
  <FirstName>Ella</FirstName>
  <LastName>Fitzgerald</LastName>
  <Grammys>14</Grammys>
  <link rel="self" href="http://dlwelchservices.com/jazz/artists/2" type="application/xml"/>
 </Artist>
 <Links>
  <link rel="edit" href="http://dlwelchservices.com/jazz/artists/2" type="application/xml"/>
  <link rel="delete" href="http://dlwelchservices.com/jazz/artists/2" type="application/xml"/>
  <link rel="/jazz/rel/home" href="http://dlwelchservices.com/jazz/artists" type="application/xml"/>
 </Links>
</JazzArtist>

And a POST to the bookmark URI will result in a 201 Created code along with the new representation of the Jazz Artists root listing that contains the newly appended artists:

201 Created
Allow: GET,POST
Content-Type: application/xml; charset=utf-8
Location: http://dlwelchservices.com/jazz/artists
...
<?xml version="1.0" encoding="utf-8"?>
<JazzArtists xmlns="http://schemas.dlwelch.com/JazzService" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Artists>
<Artist>
<FirstName>Nina</FirstName>
<LastName>Simone</LastName>
<Grammys>0</Grammys>
<link rel="self" href="http://dlwelchservices.com/jazz/artists/1" type="application/xml"/>
</Artist>
...
<Artist>
<FirstName>New</FirstName>
<LastName>Artist</LastName>
<Grammys>0</Grammys>
<link rel="self" href="http://dlwelchservices.com/jazz/artists/18" type="application/xml"/>
</Artist>
</Artists>
<Links>
<link rel="/jazz/rel/add" href="http://dlwelchservices.com/jazz/artists" type="application/xml"/>
<link rel="/jazz/rel/search" href="http://dlwelchservices.com/jazz/artists/?firstname={firstname}&lastname={lastname}&grammys={grammys}" type="application/xml"/>
<link rel="self" href="http://dlwelchservices.com/jazz/artists" type="application/xml"/>
</Links>
</JazzArtists>

Any errors generated by malformed requests or requests made to non-existent URIs should return standard HTTP error codes like 404 Not Found, 400 Bad Request, 405 Method Not Allowed and 500 Internal Server Error. For example, when a GET request is made to an artist resource that does not exist, our service returns a 404 Not Found status code and than presents the consumer with links to search or return to the bookmark URL:

404 Not Found
Allow: GET
Content-Type: application/xml; charset=utf-8
Location: http://dlwelchservices.com/jazz/artists/22
...
<?xml version="1.0" encoding="utf-8"?>
<JazzArtist xmlns="http://schemas.dlwelch.com/JazzService" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Artist/>
<Links>
<link rel="/jazz/rel/search" href="http://dlwelchservices.com/jazz/artists/?firstname={firstname}&lastname={lastname}&grammys={grammys}" type="application/xml"/>
<link rel="/jazz/rel/home" href="http://dlwelchservices.com/jazz/artists" type="application/xml"/>
</Links>
</JazzArtist>

Cache control is another standard feature of HTTP that allows our Jazz Web Service to adhere to the cache constraints of RESTful architectures. “Cache constraints require that the data within a response to a request be implicitly or explicitly labeled as cacheable or non-cacheable.”1 Since our service is quite small – only 20 maximum records are allowed – we are using an HTTP Cache-Control header of “no-cache” for all responses.

200 OK
Date: Mon, 01 Jul 2013 19:55:19 GMT
Allow: GET, PUT, DELETE
Content-Type: application/xml; charset=utf-8
Location: http://dlwelchservices.com/jazz/artists/2
Cache-Control: no-cache
...

If our service grows to the point that performance (whether on the server or client) becomes an issue, we can use a combination of HTTP standard headers like Cache-Control, Last-Modified, Age and Expires to explicitly define the cache-ability of each resource representation. We can also allow HTTP HEAD and conditional GET requests to help the client follow our cache-ability rules in accordance to our HTTP response headers.2

“All web services use HTTP, but they use it in different ways.”2 Using full-featured HTTP (as defined in RFC 2616) when making requests to resource URIs gives us a uniform interface that adheres to the REST constraints imposed upon web services in Resource-Oriented Architectures. You can follow the progress of our RESTful Jazz Web Service by navigating to the bookmark URI or using a jQuery/JavaScript client side application.


1. Fielding, Roy Thomas. Architectural Styles and the Design of Network-based Software Architectures. Doctoral dissertation, University of California, Irvine, 2000.

2. Richardson, Leonard and Ruby, Sam. RESTful Web Services. Sebastopol: O’Reilly Media, Inc., 2008. Ebook

3. Fielding, Roy Thomas. REST APIs must be hypertext-driven. Untangled – Musings of Roy T. Fielding, October 20, 2008

4. Fielding, Roy Thomas, et. al. RFC 2616 – Hypertext Transfer Protocol – HTTP/1.1. The Internet Society, June 1999

RESTful Web Services for Resource-Oriented Architectures (ROA) – Part 2 – HATEOAS

In my last post on RESTful web services for Resource-Oriented Architectures, I focused on Addressibility and the URI of the resources.1 In this article, I’ll tackle Connectedness and its relationship to the REST constraint of Hypermedia as the Engine of Application State (HATEOAS).2

In the book RESTful Web Services, HATEOAS is described by Richardson and Ruby as “Connectedness”. However, Roy Fielding says the property of connectedness is just a step towards using hypermedia to drive application state.3 In addition to providing links in our resource representations to related resources, HATEOAS is “about late binding of application alternatives that guide the client through whatever it is that we are trying to provide as a service. It is fundamental to the goal of removing all coupling aside from the standardized data formats and the initial bookmark URI.” 4 [emphasis added] So, just by knowing about HTTP and the standard data formats served on the web, you (or a machine) should be able to navigate through a RESTful web service. Moreover, you should be able to create a client application that achieves it’s desired function by navigating through and creating, editing or deleting the resources exposed by the RESTful service URIs.

Suppose we want to create a RESTful ROA web service for banking. We’ll concentrate on allowing clients to make transfers between their various accounts. First, we’ll define the bookmark URI as “/bank”. When a client requests this URI, we’ll respond with something similar to this:

200 OK
Allow: GET
Content-Type: application/xml; charset=utf-8
Location "/bank"

<bank>
 <link rel="/bank/rel/customers" type="application/xml" 
       uri="/bank/customers" />
 <link rel="/bank/rel/branches" type="application/xml" 
       uri="/bank/locations" />
 <link rel="self" type="application/xml" 
       uri="/bank" />
</bank>

The response tells us this URI only accepts GET and then gives us a few options for our next request. We’ll do a GET to the URI “/bank/customers”. Although we don’t know for sure if “/bank/customers” accepts a GET, we can give it a try since we know GET is a standard HTTP verb. If not, the response should tell us what HTTP verbs are accepted. If the web service is RESTful, a GET to any service URI will be safe.1

200 OK
Allow: GET
Content-Type: application/xml; charset=utf-8
Location: "/bank/customers"

 <customers>
  <customer>
      <id>afmorris</id>
      <link rel="self" type="application/xml" 
            uri="/bank/customers/afmorris" /> 
  </customer>
  <customer>
      <id>dlwelch</id>
      <link rel="self" type="application/xml" 
            uri="/bank/customers/dlwelch" /> 
  </customer>
   ... 
  <customer>
      <id>edmorris</id>
      <link rel="self" type="application/xml" 
            uri="/bank/customers/edmorris" /> 
  </customer>
 <link rel="self" type="application/xml" 
       uri="/bank/customers" />
 <link rel="/bank/rel/branches" type="application/xml" 
       uri="/bank/locations" /> 
 <link rel="up" type="application/xml" 
       uri="/bank" /> 
</customers>

The response to our GET is an XML document with a list of customers and their URIs. It also gives us other options we can try if this isn’t what we’re looking for. Let’s make another GET to “/bank/customers/dlwelch”. It’s a good guess this will retrieve my customer info.

200 OK
Allow: GET, PUT
Content-Type: application/xml; charset=utf-8
Location: "/bank/customers/dlwelch"

<customer>
 <id>dlwelch</id>
 <name>Dedra L. Welch</name>
 <address>100 Beach Street, Gulf Coast, TX 70000</address>
 <phone>(555) 555-0000</phone>
 <link rel="/bank/rel/accounts" type="application/xml" 
       uri="/bank/accounts/dlwelch" />
 <link rel="/bank/rel/transfers" type="application/xml" 
       uri="/bank/transferforms/dlwelch" />
 <link rel="self" type="application/xml" 
       uri="/bank/customers/dlwelch/" />
 <link rel="edit" type="application/xml" 
       uri="/bank/customers/dlwelch/" />
 <link rel="up" type="application/xml" 
       uri="/bank/customers" />
 <link rel="/bank/rel/home" type="application/xml" 
       uri="/bank" />
</customer>

The returned XML document does contain my customer info and links to other resources related to my customer account. Notice this URI will also accept a PUT. This is another standard HTTP verb and, combined with the “edit” link, tells us we can edit this representation and PUT it back to the resource URI to update our customer information. But we want to transfer money from savings to checking. So let’s do a GET to “/bank/transferforms/dlwelch”.

200 OK
Allow: GET, POST
Content-Type: application/xml; charset=utf-8
Location: "/bank/transferforms/dlwelch"

  <transferforms>
    <pendingforms>
      <link rel="self"  type="application/xml"
            uri="/bank/transferforms/dlwelch/pending" />
    </pendingforms>
    <postedforms>
      <form> 
        <id>0001</id>
        <link rel="self"  type="application/xml"
              uri="/bank/transferforms/dlwelch/posted/0001" />
      </form>
      ...
      <form> 
        <id>1233</id>
        <link rel="self"  type="application/xml"
              uri="/bank/transferforms/dlwelch/posted/1233" />
      </form>
      <link rel="self"  type="application/xml"
            uri="/bank/transferforms/dlwelch/posted" />
    </postedforms>
    <link rel="self" type="application/xml" 
          uri="/bank/transferforms/dlwelch" />
    <link rel="up" type="application/xml" 
          uri="/bank/accounts/dlwelch" />
    <link rel="/bank/rel/home" type="application/xml" 
          uri="/bank" />
    <link rel="/bank/rel/create" type="application/xml" 
          uri="/bank/transferforms/dlwelch" />
  </transferforms>

We get back an XML representation of the transfer forms available to my account. This URI accepts a POST as well as a GET. That usually means we can append a new item by POSTing to the URI. And we have a link relationship that says “create” with the same URI as the representation we just received. Odds are, we can POST to this URI to start a new transfer by creating a new transfer form. We know that a POST is neither safe nor idempotent1 but the response is encouraging us to do so. This encouragement is the first we’ve seen of our service trying to “guide the client through whatever it is that we are trying to provide”. Previously, our representation links were giving us locations, media types and relationships of connected resources. But in this response, we also have a link that tells us there is a path we can start following that will actually do something.

So let’s try POSTing to “/bank/transferforms/dlwelch”. But what do we POST? There’s nothing telling us of the data or format the service expects from the POST. We could POST the same representation that we received, as suggested by Richardson and Ruby, or we could POST with an empty message body. The response header should tell us if we make an improper POST and also what it expects from us if we try to POST again. Since POSTs are never safe, we’ll try POSTing without any data.

200 OK
Allow: GET, PUT, DELETE
Content-Type: application/xml; charset=utf-8
Location: "/bank/transferforms/dlwelch/pending/1234"

<pendingform>
 <form>
      <id>1234</id>
      <fromaccount><id /></fromaccount>
      <toaccount><id /></toaccount>
      <amount />
      <status>new</status>
 </form>
 <accounts>
    <savings>
      <account>
        <id>1</id>
        <amount>100.00</amount>
      </account>
    </savings>  
    <checking>
      <account>
        <id>4</id>
        <amount>50.00</amount>
      </account>
      <account>
        <id>6</id>
        <amount>1000.00</amount>
      <account>
    </checking>
 </accounts>
 <link rel="self" type="application/xml" 
       uri="/bank/transferforms/dlwelch/pending/1234" />
 <link rel="/bank/rel/delete" type="application/xml" 
       uri="/bank/transferforms/dlwelch/pending/1234" />
 <link rel="edit" type="application/xml" 
       uri="/bank/transferforms/dlwelch/pending/1234" />
</pendingform>

Our POST has returned a new transfer form, number 1234, with a status of “new”. The representation also has account information so we’ll know which accounts are available for transferring money and some links that describe what we should do next. This time the links are all related to the next possible steps in the transfer process. And the allowed HTTP verbs are as well. We can edit the form and PUT is back to the same URI or we can DELETE the form. Although nothing prevents us from returning to a URI we’ve already visited, no other links are provided and we’re now being actively pushed through the completion of the transfer. Let’s edit the form by adding the accounts and amount for the transfer and PUT it back to “/bank/transferforms/dlwelch/pending/1234”.

200 OK
Allow: GET, PUT, DELETE, POST
Content-Type: application/xml; charset=utf-8
Location: "/bank/transferforms/dlwelch/pending/1234"

<pendingform>
 <form>
    <id>1234</id>
    <fromaccount><id>6</id><fromaccount />
    <toaccount><id>1<id></toaccount>
    <amount>75.00</amount>
    <status>ready</status>
 </form>
 <acccounts>
    <savings>
      <account>
        <id>1</id>
        <amount>100.00</amount>
      </account>
    </savings>  
    <checking>
      <account>
        <id>4</id>
        <amount>50.00</amount>
      </account>
      <account>
        <id>6</id>
        <amount>1000.00</amount>
      <account>
    </checking>
 </accounts>
 <link rel="self" type="application/xml" 
       uri="/bank/transferforms/dlwelch/pending/1234" />
 <link rel="/bank/rel/delete" type="application/xml" 
       uri="/bank/transferforms/dlwelch/pending/1234" />
 <link rel="edit" type="application/xml" type="application/xml" 
       uri="/bank/transferforms/dlwelch/pending/1234" />
 <link rel="/bank/rel/post" type="application/xml" 
       uri="/bank/transferforms/dlwelch/pending/1234" /> 
</pendingform>

The transfer form is returned to us with a “ready” status, an additional link and another Allowed HTTP verb. It’s apparent that we can complete the transfer by POSTing it to the URI. This is “late binding of an application alternative”4 meant to nudge us through to the end of the transfer. It’s important to note that at if we had POSTed or PUT a form that could not be processed we should receive an error representation with an HTTP error code like “401 Conflict” and other late bound application alternatives – links – to guide us through correcting or cancelling the transfer. But our POST was accepted and the XML response is a representation of the new posted transfer form number 1234. Since we’ve successfully reached the end of the transfer process, we’re now offered several links from which to choose.

200 OK
Allow: GET
Content-Type: application/xml; charset=utf-8
Location: "bank/transferforms/dlwelch/posted/1234"

<postedform>
 <form>
    <id>1234</i>
    <fromaccount><id>6</id><fromaccount />
    <toaccount><id>1<id></toaccount>
    <amount>75.00</amount>
    <status>complete</status>
 </form>
 <link rel="self" type="application/xml" 
       uri="/bank/transferforms/dlwelch/posted/1234" />
 <link rel="up" type="application/xml" 
       uri="/bank/transferforms/dlwelch" />
 <link rel="/bank/rel/account/1" type="application/xml" 
       uri="/bank/accounts/dlwelch/1" />
 <link rel="/bank/rel/account/2" type="application/xml" 
       uri="/bank/accounts/dlwelch/2" />
 <link rel="/bank/rel/savings"  type="application/xml" 
       uri="/bank/accounts/dlwelch/savings" />
 <link rel="/bank/rel/checking" type="application/xml" 
       uri="/bank/accounts/dlwelch/checking" />
 <link rel="/bank/rel/customer/dlwelch" type="application/xml" 
       uri="/bank/customers/dlwelch" />
 <link rel="/bank/rel/branches" type="application/xml" 
       uri="/bank/locations" />
 <link rel="/bank/rel/home" type="application/xml" 
       uri="/bank" /> 
</postedform>

Using REST and ROA, we’ve been able to complete a typical online transaction just by “shuffling paperwork” – obtaining our desired application state by reading, editing, creating and deleting resource representations. Our URIs never contained any method or action information, they were all URIs delivering representations. The actions worked on each resource were the familiar actions that can be taken on any typical web resource – POST, GET, PUT, DELETE.

We have achieved the third level of Richardson’s Maturity Model.5

  1. Every service URI is to a resource representation. And the service is completely exposed through the resource URIs.
  2. All actions taken upon resources are achieved exclusively through our chosen uniform interface. In this case, HTTP – POST, GET, PUT, DELETE
  3. Application state is driven by the client navigating through late-bound, hypertext controls.

But how does our service stand up against Dr. Fielding’s rules for following the HATEOAS constraint?

  1. Our service, and its implied API, does not depend upon the HTTP protocol’s URI scheme. The URIs all point to “documents” in something similar to a file system structure. This could be mapped to any communication protocol – FTP for example. We could change our URIs to something like “ftp://bank/accounts/dlwelch” or “z:\bank\accounts\dlwelch” without effecting our service API or client apps – aside from changing the communication protocol.
  2. We’re using standard HTTP. No changes have been made to the protocol.
  3. Our service only uses the application/xml media type and the link relationships are obvious and self-describing. No out-of-bound knowledge is required to successfully negotiate a transfer.
  4. The resource names for our service are obviously not fixed. New URIs are created and deleted as the users move through the service. Neither does the service have a fixed hierarchy of resources. The client can easily imply the structure from the links available in the current representation.
  5. The client need never know about the resource types used on the back-end of our service. They only need to edit – using appropriate text data – and put the given xml representations back to the URI. For example, it is highly unlikely that the back-end data store of our system has a structure that’s even remotely similar to the pending transfer form representation.
  6. Once a client GETs the bookmark URI, “/bank”, all other states are arrived upon by navigating through the late-bound links provided in the current representation.

Although “there are probably other rules that I (Dr. Fielding) am forgetting”, we’ve made a solid attempt to adhere to the rules “related to the hypertext constraint that are most often violated within so-called REST APIs” – at least to the best of my understanding as a layman.6

You can follow the progress of adding HATEOAS to my RESTful ROA Jazz Service on my development site. For details on the Jazz Service please visit my previous posts on REST and WCF. In my next post on ROA Web Services, we’ll discuss the Uniform Interface.


About the “rel” Attribute: In this example, we included a rel (relationship) attribute in each of our link elements. rel indicates the relationship between the link’s uri and the current resource. Adjectives like rel=”edit” or rel=”self” are commonly used to describe well-known relationships. But if there’s not a standard relationship value you can use a custom relationship like rel=”/bank/rel/delete” which you can describe in your service API. The best part of using the rel attribute with late binding of links is that you can change the link uri without breaking client applications. The client knows what relationship it’s looking for, i.e. what state it wishes to be in, and should follow whatever uri is presented at the moment. There’s a lot more to discuss about the rel attribute, microformats, content-types etc. But I’ll save that for another article. In the meantime, I encourage you to read more about the rel attribute and it’s place in RESTful web services.


1. Richardson, Leonard and Ruby, Sam. RESTful Web Services. Sebastopol: O’Reilly Media, Inc., 2008. Ebook

2. Fielding, Roy Thomas. Architectural Styles and the Design of Network-based Software Architectures. Doctoral dissertation, University of California, Irvine, 2000.

3. Fielding, Roy Thomas. REST APIs must be hypertext-driven. Untangled – Musings of Roy T. Fielding, October 20, 2008

4. “The problem is that just being connected is not enough. Yes, it is important, and I’d love to have five or six different ways of explaining the parts of REST that are intended to help grow the Web. But hypertext as the engine of hypermedia state is also about late binding of application alternatives that guide the client through whatever it is that we are trying to provide as a service. It is fundamental to the goal of removing all coupling aside from the standardized data formats and the initial bookmark URI. My dissertation does not do a good job of explaining that (I had a hard deadline, so an entire chapter on data formats was left unwritten) but it does need to be part of REST when we teach the ideas to others.

I like the book’s emphasis on applying REST in practice and running through real examples. Dissertations are not so good for teaching people how to do something (other than to write more dissertations).”

Posted by Roy T. Fielding at 4:04:29 PM

5. Fowler, Martin. Richardson Maturity Model – steps toward the glory of REST. martinfowler.com, March, 18, 2010

6. Fielding, Roy Thomas. Specialization. Untangled – Musings of Roy T. Fielding, October 24, 2008

WCF – Visual Studio 2010 REST Web Service Project Download

Since I’ve had a few requests for a download of a Visual Studio project for a WCF REST web service, here’s a a working project that incorporates all the WCF and most of the REST tips from my blog to date.

RESTFUL WCF Demo

Please see my “About” page for copyright and disclaimer information when using any code downloaded from my blog or other sites.

WCF – Removing .svc from RESTful URIs

Addressability is one of the four properties of Resource-Oriented Architectures. An application is addressable if it exposes the interesting aspects of its data set through resources. And resources are exposed through their unique URIs.1 By default, the endpoints of an IIS hosted WCF service have the service file name in their URLs.2 For example,

http://www.mydomain.com/Service1.svc/resource1

While not un-RESTful, the “Service1.svc” part doesn’t add to the addressability of an ROA service. A resource URI should indicate the relationship of its resource to other resources. The example above would typically mean that resource1 is subordinate to Service1.svc, which isn’t the case. In fact, Service1.svc isn’t a resource at all and does not relate to any interesting aspect of our data.

With WCF we have the option of removing the .svc file reference from our URIs. First, use Visual Studio 2010 to create a new .Net 4(+) WCF Service Application.

Open the web.config.

The default, VS generated configuration is:

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer>
</configuration>

Add the aspNetCompatibilityEnabled=”true” attribute to the serviceHostingEnvironment element on line 18:

...
      </serviceBehaviors>
    </behaviors>
 <serviceHostingEnvironment multipleSiteBindingsEnabled="true"  aspNetCompatibilityEnabled="true" />
  </system.serviceModel>
...

Now add a Global.asax file to your project.

Open the Global.asax and add the following code on line 17:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
using System.Web.Routing;
using System.ServiceModel.Activation;

namespace YourNameSpaceHere
{
   public class Global : System.Web.HttpApplication
   {

      protected void Application_Start(object sender, EventArgs e)
      {
         RouteTable.Routes.Add(new ServiceRoute("", new WebServiceHostFactory(), typeof(Service1)));
      }

      protected void Session_Start(object sender, EventArgs e)
      {
          //...

Add a reference to System.ServiceModel.Activation if it is not already there:

Open the IService1.cs file and replace the auto-generated code with the following. This has nothing to do with removing the .svc file. It’s just to give you a working service. Don’t forget to use your namespace on line 9.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace YourNameSpaceHere
{
   [ServiceContract]
   public interface IService1
   {
      [OperationContract]
      [WebInvoke(Method = "GET",
          ResponseFormat = WebMessageFormat.Xml,
          UriTemplate = "artist")]
      Artist GetArtist();

   }

   [DataContract] 
   
   public class Artist
   {  [DataMember]
      public string FirstName { get; set; }
      [DataMember]
      public string LastName { get; set; }
      [DataMember]
      public string Grammys { get; set; }
      
      public Artist(string firstName, string lastName, string grammys)
      {
         this.FirstName = firstName;
         this.LastName = lastName;
         this.Grammys = grammys;
      }
   }
}

Open Service1.svc.cs and replace the code with this. Again, this is just for a working service.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;

namespace YourNameSpaceHere
{
   public class Service1 : IService1
   {
      public Artist GetArtist()
      {
         Artist player = new Artist("LastName", "FirstName", "0");
         return player;
      }

   }
}

Now modify Service1.svc.cs by adding a reference to System.ServiceModel.Activation and decorating the implementation class with the [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] attribute. This is part of removing the .svc file:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
using System.ServiceModel.Activation;

namespace YourNameSpaceHere
{
   [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
   public class Service1 : IService1
   {
      public Artist GetArtist()
      {
         Artist player = new Artist("LastName", "FirstName", "0");
         return player;
      }

   }
}

Finally, right click the Services1.svc file and View Markup:

Add the Factory=”System.ServiceModel.Activation.WebServiceHostFactory” attribute as follows:

<%@ ServiceHost Language="C#" Debug="true" 
Service="YourNameSpaceHere.Service1" CodeBehind="Service1.svc.cs" 
Factory="System.ServiceModel.Activation.WebServiceHostFactory"%>

And that’s all there is to do! Right click on the Services1.svc file and View in Browser. You’ll find the .svc file is no longer an endpoint:

Now browse to http://localhost:55685/artist to see the results:

<Artist xmlns="http://schemas.datacontract.org/2004/07/rest" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
  <FirstName>LastName</FirstName> 
  <Grammys>0</Grammys> 
  <LastName>FirstName</LastName> 
</Artist>

If you’ve built a WCF rest service before, you’ll also notice how we avoided all that configuration mess in the Web.config!

Many thanks to Steve Michelotti and his blog post “RESTful WCF Services with No svc file and No config”. Check out his article for more details on configuring WCF to not use the .svc file. He’ll also show you how to configure WCF to generate a help file for your services.


1. Richardson, Leonard and Ruby, Sam. RESTful Web Services. Sebastopol: O’Reilly Media, Inc., 2008. Ebook

2. WCF services hosted in IIS are represented as special content files (.svc files) inside the IIS application. It provides information used by IIS to initiate the WCF runtime and start the service. By default, the .svc file name is used as the base address for the service.

RESTful Web Services for Resource-Oriented Architectures (ROA) – Part 1 – URI

My previous posts on RESTful web services focused on the nuts and bolts of building a WCF web service with Visual Studio 2010 and consuming that service with client side jQuery. Although that service is RESTful to the extent it follows Richardson’s and Ruby’s first rule of thumb for REST services, it is not resource-oriented. “If the HTTP method doesn’t match the method information, the service isn’t RESTful. If the scoping information isn’t in the URI, the service isn’t resource-oriented.” 1

The original web service strictly uses HTTP verbs POST, GET, PUT and DELETE to accomplish create, read, update and delete actions. The URI used when creating a record is identical to the one used for reading information : http://mywebsite/myservices/JazzArtists.svc/artists. The differences are found in the HTTP method and the message body. When reading the artist records, we perform a GET request to the URI with no data in the body. The following Ajax call retrieves all artists:

    $.ajax({
            type: "GET",
            dataType: "json",
            async: true,
            url: 'http://mywebsite/myservices/JazzArtists.svc/artists',
            error: function(request, status, error) { alert(request.responseText) },
            success: function(data) {
                     //process return data 
            }
        });

To create a new artist record, we do a POST to the same URI and include the artist data in the message body:

    $.ajax({
            type: 'POST',
            dataType: 'json',
            async: true,
            url: 'http://mywebsite/myservices/JazzArtists.svc/artists',
            contentType: "application/json; charset=utf-8",
            data: '{"PersonObject":{"FirstName":"Shirley","LastName":"Horn","Grammys":9}}',
            error: function(request, status, error) { alert(request.responseText) },
            success: function(data) {
                     //process return data
            }
        });

The HTTP method matches the method information. To update this record, a PUT request is made to http://mywebsite/myservices/JazzArtists.svc/artists with the details about which record to update and how in the message body:

var newGrammys = 10;
$.ajax({
            type: 'PUT',
            data: '{"PersonObject":{"FirstName":"Shirley","LastName":"Horn","Grammys":' + newGrammys + '}}',
            dataType: 'json',
            async: true,
            contentType: "application/json; charset=utf-8",
            url: "http://mywebsite/myservices/JazzArtists.svc/artists",
            error: function(request, status, error) { alert(request.responseText) },
            success: function(data) {
               //process return data
            }
        });

We could have created a web service that updated the artist records through a GET request that included method information in the URI, for example, a GET to http://mywebsite/myservices/JazzArtists.svc/artists?action=Add&FName=Shirley&LName=Horn&NewGrammys=10. However, this would not have been a RESTful service since the method (action=Add) does not match the HTTP method (GET).

Since the method information matches the HTTP method for each request, my previous service follows Richard’s and Ruby’s first rule of thumb for RESTfulness; but, this service is not resource-oriented. The first problem lies in the PUT and DELETE requests. The scope is not in the URI which breaks the second rule of thumb. Deleting an artist is accomplished by a DELETE request to http://mywebsite/myservices/JazzArtists.svc/artists with the name of the artist to delete (the scope) contained in the message body.

        $.ajax({
            type: 'DELETE',
            data: '{"PersonObject":{{"FirstName":"Shirley","LastName":"Horn","Grammys":0}}',
            dataType: 'json',
            async: true,
            contentType: "application/json; charset=utf-8",
            url: http://mywebsite/myservices/JazzArtists.svc/artists,
            error: function(request, status, error) { alert(request.responseText) },
            success: function(data) {
               //process results
            }
        });

My new web service corrects this by including the scope in the URI. A DELETE request made to http://mywebsite/myservices/JazzService.svc/artists/127 will remove record 127 from the target data source.

        $.ajax({
            type: 'DELETE',
            dataType: "xml",
            async: true,
            url: 'http://mywebsite/myservices/JazzService.svc/artists/' + artistId;,
            error: function(request, status, error) { alert(request.responseText) },
            success: function(data) { 
                  //process return data
            }
        });

The same modification is made to the PUT method with the edit information included in the body.

var artistId=127;
$.ajax({
            type: 'PUT',
            data: '<Person xmlns="http://schemas.datacontract.org/2004/07/RESTful" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">'
                  + '<ArtistID>0</ArtistID>'
                  + '<FirstName>Ella</FirstName>'
                  + '<Grammys>14</Grammys>'
                  + '<LastName>Fitzgerald</LastName>'
                  + '</Person>',
            dataType: 'xml',
            async: true,
            contentType: "text/xml",
            processData: false,
            url: 'http://mywebsite/myservices/JazzService.svc/artists/' + artistId,
            error: function(request, status, error) { alert(request.responseText) },
            success: function(data) {
                //process return data
            }
        });

Notice that the real artistId is not included in the message body, only in the URI.

We can see the more RESTful, resource-oriented nature of the new service by inspecting its contracts:


    [DataContract]
    public class Person
    {
        [DataMember]
        public int ArtistID { get; set; }

        [DataMember]
        public string FirstName { get; set; }

        [DataMember]
        public string LastName { get; set; }

        [DataMember]
        public int Grammys { get; set; }

        public Person(int artistid, string firstName, string lastName, int grammys)
        {
            this.ArtistID = artistid;
            this.FirstName = firstName;
            this.LastName = lastName;
            this.Grammys = grammys;
        }

    }
    [ServiceContract]
    public interface IJazzService
    {
        [OperationContract]
        [WebInvoke(Method = "GET",
            ResponseFormat = WebMessageFormat.Xml,
            UriTemplate = "artists/{id}")]
        Person GetArtist(string id);

        [OperationContract]
        [WebInvoke(Method = "GET",
            ResponseFormat = WebMessageFormat.Xml,
            UriTemplate = "artists")]
        List<Person> GetAllArtists();


        [OperationContract]
        [WebInvoke(Method = "POST",
            ResponseFormat = WebMessageFormat.Xml,
            RequestFormat = WebMessageFormat.Xml,
            UriTemplate = "artists")]
        bool PostArtist(Person PersonObject);

        [OperationContract]
        [WebInvoke(Method = "DELETE",
            ResponseFormat = WebMessageFormat.Xml,
            RequestFormat = WebMessageFormat.Xml,
            UriTemplate = "artists/{id}")]
        bool DeleteArtist(string id);

        [OperationContract]
        [WebInvoke(Method = "PUT",
            ResponseFormat = WebMessageFormat.Xml,
            RequestFormat = WebMessageFormat.Xml,
            UriTemplate = "artists/{id}")]
        bool PutArtist(Person PersonObject, string id);

    }

The operations on the group of artists as a whole are completed using POST and GET against the service root URI: /JazzService.svc/artists. Reading, updating and deleting of individual artists are accomplished through their own, individual URI: /JazzService.svc/artists/{artistID}. Thus, a URI is exposed for every piece of data (the group and each individual) on which the client is allowed to operate.

Additionally, the URI has no indication of the method being used. It only points to the resource (data). All method information is contained in the HTTP method: POST, GET, PUT, DELETE.

By restricting the method information to the HTTP method, putting the scope information in the URI and exposing a URI for each resource, this new service meets Richardson’s and Ruby’s basic criteria for a RESTful, resource-oriented web sevices. But we aren’t done with the service if we want it to be truly RESTful. In my next REST post, we’ll discuss the REST constraint of Hypermedia as the Engine of Application State (HATEOAS) and how we can add it to our Jazz Artist web service.

You can see the current working example of this service on my development site.


1. Richardson, Leonard and Ruby, Sam. RESTful Web Services. Sebastopol: O’Reilly Media, Inc., 2008. Ebook

Consuming a RESTful web service with jQuery and Ajax

In my last post, we created a REST WCF web service using Visual Studio 2010. In this article, we’ll write a client side web applicaiton that uses jQuery and Ajax to consume a REST web service.

First, create an HTML page that includes a reference to a jQuery library, a <div> tag where we’ll display the service output, a button that will fire the Ajax request to the web service and one that will clear the output <div>.


<html>
<head>
<title>Consume a REST Web Service</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.2.min.js"/>
</head>
<body>
<p><div id="myOutput">Output Goes Here</div><p>
<p><input id="myButton" value="Get Artist" type="submit" /></p>
<p><input id="myClearButton" value="Clear Artist" type="submit" /></p>


Next, add the jQuery to run when the Get Artist button is clicked.

<script type="text/javascript">
 $("#myButton").click(function() {
        var artistURL = "http://development.dlwelch.com/examples/restservice/JazzArtists.svc/json/Shirley";
        var returnData = "";
        $.ajax({
            type: "GET",
            dataType: "json",
            async: true,
            url: artistURL,
            error: function(request, status, error) { alert(request.responseText) },
            success: function(data) {
                $("div#myOutput").html(" ");
                returnData = "<table style='font-size:8pt;'><tr><th>Artist</th><th>Grammys</th></tr>";
                for (prop in data) {
                    if (!data.hasOwnProperty(prop)) { continue; }
                    if (data[prop] != null) {
                        for (var i = 0; i < data[prop].length; i++) {
                            returnData += "<tr><td>" + data[prop][i]["FirstName"] 
                                       + " " + data[prop][i]["LastName"] + "</td><td align='right'>" 
                                       + data[prop][i]["Grammy"] + "</td></tr>";
                        }
                    }
                }
                returnData = returnData + "</table>";
                $("div#myOutput").html(returnData);
            }
        });
        return (false);
    });
</script>

...

Code line 3 defines the URI of the resource, in our case, the artist Shirley. Line 6 indicates we are sending an HTTP GET request to the resource and line 7 says we’ll evaluate the response as JSON and send a JavaScript object back to our success function on line 11. Since a JavaScript object was returned, line 14 starts the loop to find the property holding the response data. Line 15 test the current property to see if it’s a built in property of a JavaScript object. If so, skip it. Once we reach the property with our data, we loop through all the artist objects and create our HTML string for the output <div>.

Finally, add the jQuery to clear the output and finish your HTML.

<script type="text/javascript">
 $("#myClearButton").click(function() {
        $("div#myOutput").html("Output Goes Here");
        return (false);
    });

</script>


</body>
</html>


Your page should look like this. Click on the Get Artist button to see it work!



You can see a working example and grab the code for Ajax calls of all four HTTP verbs on my development site in the WCF RESTful Web Service example.

Creating RESTful WCF Web Services Using Visual Studio 2010

Representational State Transfer (REST) is an architectural style used to build distributed systems. First proposed in 2000 by Roy Thomas Fielding in his doctoral dissertation “Architectural Styles and the Design of Network-based Software Architectures”, REST is now, or will soon be, the predominant architecture for building web services. However, there’s a lot of discussion about the true definition of a RESTful web service. One real world discussion that helped me understand RESTfulness is this article from IBM’s Alex Rodriguez. My own, rather distilled, working definition of a RESTful service is one that uses the standard HTTP verbs POST, GET, PUT and DELETE – as intended and defined in RFC 2616 – and a URI to accomplish resource CRUD (create, read, update, delete).1

As a .NET developer, I use Windows Communication Foundation (WCF) to create web services. This post shows you how to use Visual Studio 2010 to create a basic REST service that supports each HTTP verb.

Create a WCF Service Application project named RestService:

Delete IService1.cs and Service1.cvs that were created for you by VS:

Add a new WCF service named JazzArtists:

Visual studio will add 2 files to your project named IJazzArtists.cs and JazzArtists.svc and its associated code behind page.

Next, we need to write the service contract. Replace the contents of IJazzArtists.cs with the following code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.ServiceModel.Web;

namespace RestService
{
    [DataContract]
    public class Person
    {
        [DataMember]
        public string FirstName { get; set; }

        [DataMember]
        public string LastName { get; set; }

        [DataMember]
        public int Grammys { get; set; }

        public Person(string firstName, string lastName, int grammys)
        {
            this.FirstName = firstName;
            this.LastName = lastName;
            this.Grammys = grammys;
        }
    }

    [ServiceContract]
    public interface IJazzArtists
    {
        [OperationContract]
        [WebInvoke(Method = "GET",
            ResponseFormat = WebMessageFormat.Xml,
            BodyStyle = WebMessageBodyStyle.Wrapped,
            UriTemplate = "xml/{id}")]
        string XMLData(string id);

        [OperationContract]
        [WebInvoke(Method = "GET",
            ResponseFormat = WebMessageFormat.Json,
            BodyStyle = WebMessageBodyStyle.Wrapped,
            UriTemplate = "json/{firstn}")]
        List<Person> JSONData(string firstn);

        [OperationContract]
        [WebInvoke(Method = "GET",
            ResponseFormat = WebMessageFormat.Json,
            BodyStyle = WebMessageBodyStyle.Wrapped,
            UriTemplate = "json")]
        List<Person> JSONDataAll();

        [OperationContract]
        [WebInvoke(Method = "POST",
            ResponseFormat = WebMessageFormat.Json,
            RequestFormat = WebMessageFormat.Json,
            BodyStyle = WebMessageBodyStyle.Wrapped,
            UriTemplate = "json")]
        bool JSONDataPost(Person PersonObject);

        [OperationContract]
        [WebInvoke(Method = "DELETE",
            ResponseFormat = WebMessageFormat.Json,
            RequestFormat = WebMessageFormat.Json,
            BodyStyle = WebMessageBodyStyle.Wrapped,
            UriTemplate = "json")]
        bool JSONDataDelete(Person PersonObject);

        [OperationContract]
        [WebInvoke(Method = "PUT",
            ResponseFormat = WebMessageFormat.Json,
            RequestFormat = WebMessageFormat.Json,
            BodyStyle = WebMessageBodyStyle.Wrapped,
            UriTemplate = "json")]
        bool JSONDataPut(Person PersonObject);


    }
}

The [DataContract] defines the data types and structures of resources that will be transferred between your application and the web service. The [ServiceContract] defines how each HTTP verb request to the specifed URI will be handled by the web service.

In this example, the first [OperationContract] is for GET requests made to URLs constructed like http://yourdomain.com/RestService.svc/xml/Shirley. All requests to this URL will receive an XML response since ResponseFormat = WebMessageFormat.Xml on code line 36. The XML returned data

  <XMLDataResponse xmlns="http://tempuri.org/">
  <XMLDataResult>Your name is Shirley</XMLDataResult> 
  </XMLDataResponse>

is the result of the method XMLData(string id) – which we’ll discuss momentarily.

The next [OperationContract] is for a GET request to URLs like http://yourdomain.com/RestService.svc/json/Shirley. The result returned from this request is a in JSON formatted Person list with one row, for example:

{"JSONDataResult":[{"FirstName":"Shirley","Grammys":1,"LastName":"Horn"}]}

The next GET contract is used to read all Persons. Notice it has a different URI than the previous. In the first URI – /json/{firstn} – we specified which person to get. The second URI does not. So when you GET from http://yourdomain.com/RestService.svc/json, the return is a list of all Persons:

{"JSONDataAllResult":[{"FirstName":"Billie","Grammys":10,"LastName":"Holiday"},
                      {"FirstName":"Shirley","Grammys":4,"LastName":"Horn"},
                      {"FirstName":"Ella","Grammys":20,"LastName":"Fitzgerald"}]}

The POST [OperationContract] for the URL http://yourdomain.com/RestService.svc/json expects the posted data in the request package to conform to the Person class definition and to be in JSON format:

{"PersonObject":{"FirstName":"Shirley","LastName":"Horn","Grammys":4}}

Notice the JSON wrapper key name “PersonObject” is the same name used in the POST [OperationContract] on code line 61. We will discuss the requirements for the “input” data of the POST request in greater detail in my next post.

The response to the POST request is the JSON formatted result of method JSONDataPost(Person PersonObject).

{"JSONDataResult":true}

PUT and DELETE are similarly implemented.

Now we need to define the methods that run when the HTTP requests are made to the URIs. Replace the contents of JazzArtists.svc.cs with this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace RestService
{
    public class JazzArtists : IJazzArtists
    {

        public string XMLData(string id)
        {
            return "Your name is " + id;
        }

        public List<Person> JSONData(string firstn)
        {   //code to Read ONE person goes here
            string lastn = "Horn";
            int nogrammys = 1;
            List<Person> players = new List<Person>();
            players.Add(new Person(firstn, lastn, nogrammys));
            return players;
        }

        public List<Person> JSONDataAll()
        {   //code to Read ALL Persons go here
            List<Person> players = new List<Person>();
            players.Add(new Person("FirstName", "LastName", 0));
            return players;
        }

        public bool JSONDataPost(Person PersonObject)
        {   //code to Create the Person goes here
            return true;
        }

        public bool JSONDataDelete(Person PersonObject)
        {   //code to Delete the specified Person
            return true;
        }

        public bool JSONDataPut(Person PersonObject)
        {   //code to Update the specified Person goes here
            return true;
        }
    }
}

How easy is that! Just fill in the details for your project and make sure your method names and types are the same as those specifed in the contract.

Finally, since the default communication binding for a WCF web services is SOAP, we need to change the web.config to use REST instead.

In the system.serviceModel section, delete both the service for Service1:

and the associated behavior:

since we have deleted Service1 from the project. Also delete the indentity in your JazzArtists service:

WCF will infer an appropriate identity automatically.

Now change the endpoint binding for JazzArtists to webHttpBinding and the behaviorConfiguration to web. Add the endpointBehaviors section as well:

The system.serviceModel should look like this:

<system.serviceModel>
    <services>
      <service behaviorConfiguration="RestService.JazzArtistsBehavior"
        name="RestService.JazzArtists">
        <endpoint address="" binding="webHttpBinding" 
          contract="RestService.IJazzArtists" behaviorConfiguration="web">
        </endpoint>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior name="RestService.JazzArtistsBehavior">
          <serviceMetadata httpGetEnabled="false" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="web">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>

You may need to make more changes to your web.config depending upon the hosting environment. Mine runs on a shared hosting plan so I had to add a serviceHostingEnvironment section to my system.serviceModel to specify the correct prefix:

I also had to add a buildProviders in the compilation section to properly handle .svc files:

You can test drive a working REST service similar to this one on my development site example WCF RESTful Web Service. My next post will demonstrate how to consume a REST service using client side jQuery and Ajax.


1. This post concentrates on the details of creating a REST service using WCF and Visual Studio 2010. However, the service we built is not as RESTful as it could be. A future post will demonstrate a few changes that will better align this web service with the principles of REST and Resource Oriented Architecture.