Ron Jacobs

Windows Workflow Foundation

The Canonical REST Entity Service

The Canonical REST Entity Service

  • Comments 13

Recently I was doing a review of some .NET 3.5 WCF REST code based on the REST Starter Kit to see what it would take to move it to .NET 4.

The more I looked at the code and thought about it deeply I realized that the mechanics of exposing a service over HTTP are not the hard part.  What is difficult is to get the semantics of HTTP right.  After spending some time reading through the HTTP spec I took a stab at creating the Canonical REST Entity Service

“ca·non·i·cal [ kə nónnik'l ] conforming to general principles: conforming to accepted principles or standard practice'”

What I was after was a set of requirements that I could verify about the way in which a REST Entity Service should behave.  Here is what I came up with.

First of all I learned that Canonical is spelled with 1 n and not two as in “Cannonical” [sic] which I used all over the place in this code so… sorry. 

Watch

Get Microsoft Silverlight

Download

Canonical REST Service (MSDN Code Gallery)

Canonical REST Entity Service URI Map

Base URI: http://tempuri.org/Resource where Resource is the name of the REST collection (i.e. Customers, Orders etc.)

Web Formats XML and JSON are supported for all request/response messages

URI Template HTTP Method Description Status Response Content Response Contains
/{key} GET Gets a resource by key 200 OK Serialized resource
      304 Not Modified Empty
      400 Bad Request Empty or Serialized error message
      404 Not Found Empty
/?skip={skip}&take={take} GET Gets a list of resources starting with skip+1 and returning take 200 OK Serialized resources
      400 Bad Request Empty or Serialized error message
/ POST Adds a resource to the collection 200 OK Serialized resource
      204 No Content Empty
      400 Bad Request Empty or Serialized error message
      409 Conflict Empty or Serialized error message
/{key} PUT Adds or Updates a resource identified by {key}. Some services might not allow add with PUT. If you return the updated resource, return 200. If you don't return 204. 200 OK Updated resource
      204 No Content Empty
      400 Bad Request Empty or Serialized error message
      404 Not Found Empty or Serialized error message
      409 Conflict Empty or Serialized error message
/{key} DELETE Removes the resource identified by {key}. If you return the resource removed, return 200. If you don't return 204. 200 OK Deleted Resource
      204 No Content Empty
      400 Bad Request Empty or Serialized error message
      404 Not Found Empty or Serialized error message
      409 Conflict Empty or Serialized error message

GET TESTS

GET Spec http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

Tests GET /{key}

  1. GET MUST return a resource given a key if the resource with that key exists
  2. GET MUST return 400-BadRequest if the key is invalid
  3. GET MUST return 404-NotFound if the key is not found
  4. GET MUST return 304-NotModified if Conditional GET conditions are met using If-None-Match
  5. GET SHOULD return an ETag header

Tests GET /?skip={skip}&take={take}

  1. GET MUST skip {skip} resources in the collection and return up to {take} resources.
  2. GET MUST return resources starting with the first one when {skip} is not defined
  3. GET MUST return zero resources when {skip} is greater than the number of resources in the collection
  4. GET MUST return 400-BadRequest if {skip} is < 0
  5. GET MUST return zero or more resources when {take} is not provided
  6. GET MUST return 400-BadRequest if {take} is < 0

POST TESTS

POST Spec http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

Tests POST /

  1. POST MUST append a valid resource to the resource collection using a server generated key and return 201 – Created with a location header, entity tag and entity body
  2. POST MUST return 400-Bad Request if the entity is invalid
  3. POST MUST return 409-Conflict if the entity conflicts with another entity
  4. POST MUST ignore writes to entity fields the server considers read only

PUT TESTS

PUT Spec http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

Tests PUT /{key}

  1. PUT MUST Update the entity identified by the URI if it exists and return 200-OK with the modified entity and etag header
  2. PUT MAY Add a new entity using the key provided in the URI and return 201-Created with entity location and etag
  3. PUT MUST respect the Precondition If-Match
  4. PUT MUST be Idempotent
  5. PUT MUST NOT alter the key of the entity so that it does not match the key of the URI
  6. PUT MUST return 400-BadRequest if the entity is invalid
  7. PUT MUST return 400-BadRequest if the key is invalid
  8. PUT MUST ignore writes to entity fields the server considers read only
  9. PUT MUST return 404-NotFound if the server does not allow new entities to be added with PUT

DELETE TESTS

DELETE Spec http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

Tests DELETE /{key}

  1. DELETE SHOULD delete an entity that exists and return 200-OK with the deleted entity or 204-No Content if the response does not include the entity
  2. DELETE SHOULD be idempotent
  3. DELETE SHOULD return with 412-PreconditionFailed if no matching entity for If-Match etag
  4. DELETE SHOULD succeed if matching entity for If-Match etag
  5. DELETE SHOULD succeed if wildcard used in If-Match etag
  6. DELETE SHOULD return 202-Accepted if the request to delete has not been enacted
  7. DELETE SHOULD return 400-BadRequest if the key is invalid
  • Finally, my favorite WCF REST solution is getting some well deserved love!

    Thank you!

  • I wonder what the RESTful bigots will say about this?

  • @DaRage - well I hope we can dialog about it and make it better.  I'm actually trying to build something that is faithful to the ideals of REST.

  • Thanks for your work on this project. It would be nice to see a fully supported WCF REST template for Visual Studio 2010 and ASP.NET 4.0 from Microsoft that just works "straight out of the box" for both both development server and production server. The WCF team has been working on WCF for how many years now? And there's still no easy to use implementation of REST in WCF with a Microsoft supported template for REST in WCF?!? Even after all these years of WCF?!? So why should we bother to use WCF for REST? Why not just use ASP.NET MVC? It seems to me that the MVC team is doing a much better job than the WCF team in building a framework that supports REST style programming for the web? Maybe your work on this current project of yours will lead to a fully supported template for REST in WCF. If so, then there needs to be a clear and compelling demonstration that WCF is not going to cause the headaches that it has caused for the past several years...

  • I hope so too Ron. However, I have an opinion that I would like to voice here about REST and WCF. I think, and I'm sure you heard that before, that RESTifying WCF is changing it to something that it was not designed for, in other words, bastardizing it.

    The foundation of WCF of decoupling from transport and ABC simply don't apply to REST and adjusting WCF to be RESTful would work but it will not be simple. Because one of the main driving forces of REST is simplicity i think this approach will have limited success. I speculate that the effort of unifying WCF and REST is more driven by business needs than technological ones and because people who do REST are such technological bigots as I mentioned this thing will not fly with them.

    I think that creating a parallel RESTful WCF and WF frameworks from scratch will be much simpler and leaner and maybe they will become the dominant one framework int the future.

  • @DaRage - Just wait - the team is working on some really cool new stuff for REST that will give you what you are looking for (I hope).

  • What do we need to install to open this in Visual Studio 2010.  A pristine install of VS 2010 Premium says the project type is not supported.

  • @VS2010 Compatible... I'm not sure wht the issue is.  It is just a Web Project, a Test Project and a Class Library project.  Nothing unusual there.

  • DaRage - I agree with you, and your remarks seem to echo my concerns that even if the WCF team might be trying to RESTify WCF, at least in my opinion, they are not succeeding in a coherent and fully supported manner that builds confidence. So then if RESTifying WCF is not the preferred approach, should there be a RESTified MCV with full tooling/testing support for RESTful programming? Or should it be a new framework entirely devoted to REST and only REST?

    ronjacobs - Is the really cool new stuff for REST built on top of WCF, on top of MCV, or as discussed here, completely independent of either WCF or MCV?

  • @DaRage - The new stuff is new stuff :-)  

    What really matters is what it does and how it works.  When the time is right (hopefully soon) we will begin sharing it with you on Codeplex to get your feedback.

    My first goal will be to update this sample based on the new stuff - that is why I built the tests - they will be a good barometer for insuring the new stuff is really working as it should.

  • @DaRage, @Carl

    Thanks for all the feedback. I am driving our HTTP/REST story going forward. I hear all your concerns. We are not looking to simply retrofit on top of our existing stuff. We are looking at a pure resource oriented model, and how to best deliver on that. That doesn't mean we won't use some of our existing bits, but we are really focused on the ideal experience over how can we just use what we have. We're also focused heavily on involving the community both inside and outside of .NET in the work we are doing. This includes getting source out there sooner which is something we're working on.

    I have posted early thinking on this here: codebetter.com/.../resting-from-mef-or-the-mef-dealer-is-at-rest.aspx

    I'd be happy to chat with either of you more to hear your concerns.

    Thanks

    Glenn

  • So this isn't SOAP or OData, but this returns XML of a Resource type.  Also this is NOT WCF Data Services but looks like WCF Services.  NOW I am confused as what to use.  

  • @Allan - Hang on - we are mixing things up a bit.  What I built is based on WCF WebHttp Services with stock .NET 4 and a set of tests that can verify a service behaving correctly.

    What Glen is talking about is next-gen stuff

Page 1 of 1 (13 items)