Later today on this weblog: still more REST crap!
Fri Jun 01 2007 08:57:
InfoQ, the famous "enterprise software development community", has an interview with Sam and me, as well as an excerpt from the book. Enjoy!
Later today on this weblog: still more REST crap!
Fri Jun 01 2007 08:57:
InfoQ, the famous "enterprise software development community", has an interview with Sam and me, as well as an excerpt from the book. Enjoy!
I wrote this entry by going through the two white papers and trying
to discern what resources the system exposed, what parts of the
uniform interface they support, what representations are served and
accepted, and how resources link to each other. This is the same
approach I took when analysing the Atom Publishing Protocol for
RWS. I'm pretty sure I got everything right, but I'm not totally sure about the association resources. I've presented my findings in a form much like the one I'd like to see if I was trying to figure out how a RESTful web service worked. I hope this helps.
Introduction
Astoria is a framework for a certain class of web services: those
that expose access to tables and rows in a database. In this regard
it's similar to ActiveResource. The resources exposed might not
correspond exactly to the underlying database objects, but they will
look like database tables and there will be some kind of mapping to a
real database.
The "overview" whitepaper starts out covering some of the ground
covered in RWS chapter 11. It points out that Ajax applications
have a different architecture than traditional web
applications. They're GUI applications where the GUI events are
handled by an invisible web service client. Astoria wants to provide
the services those clients will access.
Astoria "uses URIs to point to pieces of data"
(ie. resources). Astoria's "data services" are "surfaced to the web as
a REST-style resource collection that is addressable with URIs and
that agents can interact with using the usual HTTP verbs such as GET,
POST or DELETE." So far so good. They talk the talk.
Meet the Resources
An Astoria service defines six basic kinds of resources. A lot of them correspond directly to a resource type in ActiveResource
and/or the Atom Publishing Protocol. This makes sense because all three are solving similar problems: exposing collections and the objects in the collections.
A entity is identified with its collection name and then some kind
of unique index: maybe /data.svc/Customers[4] or
/data.svc/Customers[ALFKI]
(Note: the white papers also talk about a non-resource
"association" that's part of the state of an entity. It's a link from
one entity to another, as part of a relationship that's not
many-to-many. For instance, every order associated with
Customers[ALFKI] will contain a link in its representation to
Customers[ALFKI]. These associations are not
resources, because they don't have their own URIs; they only show up
in representations of entities. When I say "association" I'm talking
about association resources.)
The uniform interface
What do other frameworks do? The APP and Rails define GET and POST
on a "collection" resource; and GET, PUT, and DELETE on a "member"
resource. The APP defines GET on a service document. Where Astoria has
similar resources, it exposes the same interface. The only part that's
difficult to explain is the difference between POST on a regular
collection and POST on a scoped collection.
The "overview" white paper has a confusing paragraph about
Astoria's use of the uniform interface (the one that begins "For URIs
that represent a specific entity...") which is either wrong or very
poorly worded: I read it as saying that entities respond to POST,
which doesn't make sense. Here's what I got from the "using" white
paper, in convenient table form:
I'll just explain "Create an association between two entities,"
shall I? Here's a scoped entity-set:
/data.svc/Territories[99999]/Employees. It's a collection of
employees, scoped to a particular territory. There's a many-to-many
relationship between territories and employees (at least according to
the whitepaper). If I want to associate an existing employee with
territory 99999, I POST a representation of the employee to the scoped
entity-set. (The representation just contains the employee's database
ID.) A new resource is created at a URI like
/data.svc/Territories[99999]/Employees[3]: it's the
relationship between territory 99999 and employee 3.
Representations
"Currently Astoria can represent data in plain XML, JSON
(JavaScript Object Notation) and in a subset of RDF+XML."
Representations are selected through content negotiation or through a
query string parameter.
Incoming representations have the same format as outgoing
representations.
Links
So far, so good. But now Astoria must truly pass through the
RESTful crucible. How well does it use hypermedia? Pretty well,
actually. The "site map" resource links to all the top-level
entity-sets. Entity-sets link to entities and to appropriate entity-sets scoped to each entity. A sample XML representation of
http://myserver/data.svc/Customers gives the URI to each
customer in the list, and an "orders" link to each customer's
orders. This is excellent, much better than ActiveResource.
Second, I get the impression that a scoped entity-set links to the
entities inside the set, but not to the corresponding association
resources. That would mean if you want to DELETE an association, you
need to construct the URI yourself. This is a guess because I didn't
see a representation of a scoped collection.
Miscellaneous
As with Yahoo!'s web services, Astoria's JSON representations can
be wrapped in a callback function that calls your code. This lets you
use the Javascript on Demand hack described in chapter 11, to run code
from a foreign web service in your Ajax application. (The "using"
white paper calls this JSONP, for JSON with Padding.)
The "overview" whitepaper says the pagination variables are
skip and take, but the "using" whitepaper says
they're skip and top. Whitepaper bug!
You can create "service operations", which are arbitrary .NET
methods exposed through GET requests. The example given is a custom
query, but in practice this feature will encourage a REST-RPC style of
programming. However, "[i]n the future attributes will be extended so
that the specific HTTP method can be controlled." And the hooks for
error checking and triggers are exposed in a way I think will promote
RESTful design.
Sam's favorite section: what about caching and ETags? "Astoria
services also leverage other aspects such as the well-established HTTP
caching infrastructure. Data services can be configured to set various
caching-related HTTP headers to cache at the web server, client agent,
or intermediate agents such as proxies." It sounds like caching works
automatically--with a tie-in to the database engine? No mention of
ETags in either white paper.
"Microsoft may have patents, patent applications, trademarks,
copyrights, or other intellectual property rights covering subject
matter in this document." I sure hope not.
Verdict
Astoria services are in fact RESTful and resource-oriented. They're
very similar to APP services, though not so much that the APP is
obviously a better base. The main thing I'd worry about is the
tendency for programmers to use the hooks for writing RPC-style
code. I'd head this off at the pass with the promised support for
service operations triggered by other HTTP methods, some RESTful
examples, and maybe a bit of theory. But I don't know the best way to herd
Microsoft programmers.
(6) Fri Jun 01 2007 14:30 How's My Driving? #1: Microsoft Astoria:
Sumana wants me to post some analyses of web services and talk about how they are or could be made more RESTful. Alex
Barnett wants me to look at Microsoft's Astoria project (so does
Microsoft, apparently, since they named it after where I live). I love
it when a plan comes together. Here is some free consulting for
Microsoft, based entirely on my readings of white papers ("overview" and
"using").
Resource
GET
POST
PUT
DELETE
Entity-set list
X
-
-
-
Entity-set (collection)
X
X (Create a new entity)
-
-
Virtual entity-set
X
-
-
-
Entity (member)
X
-
X
X
Scoped entity-set
X
X (Create an association between two entities)
-
-
Association
X
-
X
X
This lame diagram shows my interpretation of how Astoria resources
link to each other. There are two minor missing pieces. First, there's
no way to get to a virtual entity-set without constructing the URI
manually. This is understandable because those URIs can be about as
complicated as SQL expressions. You can't design an HTML 4 form that
can generate all of them. You could support a simplified version with
a HTML 5 or WADL form. I'm also thinking of a series of resources that
work like Bugzilla's advanced query builder to support every kind of
query building. It might not be worth it.
First I took the puff pastry out to thaw and made the filling. This starts with crimini mushrooms, chopped up and sauteed. Add some salt, pepper, and thyme. Then you chop up some asparagus stalks and steam them.
To those two add a cheese sauce. I made a roux with about a tablespoon each of butter and flour, then added a quarter-cup of milk and stirred in about three ounces of blue cheese.
By this time the puff pastry was thawed. My pastry was folded into fourths so it was natural to turn each fourth into a Wellington. I cut the pastry into fourths and brushed around the edges of each with egg wash. I stuck filling in the middle and folded the pastry over to make a Wellington/burrito shape. 20 minutes at 400 degrees gives delicious mushroom-asparagus pastries.
We ate these with a salad assembled from the farmer's market, and dessert was strawberries from same.
Fri Jun 01 2007 21:46 Mushroom Wellington:
When we went to England we had a great lunch in Cambridge at a place called Rainbow Cafe. The highlight of my meal was a "champignon torsade", a puff pastry twist with mushrooms. Today one of Sumana's coworkers came over and I made a similar dish for dinner. It turned out incredibly well so I'll give you a recipe.
![]() | Unless otherwise noted, all content licensed by Leonard Richardson under a Creative Commons License. |