Tuesday, October 23, 2007

Push & Pull Naming Standard & the Uniform Interface

The uniform interface is great. Resource name + GET, POST, PUT, DELETE & you are done. This is an amazingly simple / powerful constraint of the REST architectural style.

I spent a little time today thinking through a naming standard for our integration architecture. We need to support Push & Pull. This is essentially REST/AtomPub & Messaging.

For REST, I liked what RESTful Web Services had to say:

. . . So which is it? URI as UI, or URI opacity? For once in this book I'm going to give you the cop-out answer: it depends. It depends on which is worse,for your clients: a URI that has no visible relationship to the resource it names, or a URI that breaks when its resource state changes. I almost always come down on the side of URI as UI, but that's just my opinion.

It references URL as UI (Jakob Nielsen) and Universal Resource Identifiers -- Axioms of Web Architecture (Tim Berners-Lee)

URI Templates seem like a natural fit for specifying URI standards & URIs that are in use.

What about on the Push side (i.e., traditional MOM/XMPP) - what is the analogue? Is there one?

I toyed with the idea of using the same verbs (GET & POST at least), but I think that the semantics are different enough with messaging that it is either too clever or just lame to use a subset of the same verbs. The main issue is that GET isn't idempotent in messaging. I guess you could use GET for Browse, DELETE to pop off a queue, and POST to send a message, but it just seems too contrived to me. These are different styles - why break people's head with foolish consistency?

In the past I have had good luck with NOUN.VERB in messaging which is similar to REST in a way if you standardize on it.


Any other ideas / experiences?


Sarge said...

I've had good success over the years with staying as close to English, e.g., adjective-noun for class names, verb-object for method names, etc. Hence, my vote is for NOUN.VERB.

Mike Dierken said...

What is it you are trying to do?
Model a collection of messages and devise HTTP requests to access that collection?
Or are you thinking about what HTTP requests to use to transfer knowledge of an 'event' to a set of subscribers?

Can you describe your situation with a scenario?

fuzzy said...

Hi Mike Dierken,

I think we have a good enough handle on HTTP URI naming. We will have the typical REST type interactions including the processing of collections. I presume we'll use AtomPub at least for inspiration there. Overtime we might add things to it (e.g., get a search result of a collection in a feed like OpenSearch/GData).

The context is large scale integration. We are using a domain model where major systems are grouped together in domains. We are focusing on the integration of these domains in a consistent way. What a particular domain does inside is largely its business, but we want to see a consistent approach for integrating across domains (i.e., transfer approach, URI naming, data formats, security, etc.).

We see HTTP as the preferred mechanism to transfer data between domains. As much as possible, we want "the web" to be in between domains.

But MOM does play a role in push scenarios for us. Also it can be convenient for for mainframes.

So any domain will interact with a set of URIs and a set of Queues. It may be that putting a message on a queue will result in some cases in that data being added to a feed.

URIs for each domain will be prefixed with the domain name. For example: /accounting/billable_account

I'm feeling ok with the URI naming, but was curious if anyone had ideas on the Queue / Push side.



fuzzyBSc said...

When it comes to a push interface, I don't think you can get away from the need to use idempot requests. A client needs to be able to issue the request again after a timeout, with confidence that the effect will be the same as issuing the request once. For that reason I don't use POST in my architecture. I use GET, PUT, DELETE, and also a subscription mechanism.
PUT http://example.com/collection?guid=... text/plain 2
GET http://example.com/collection (returns 1 2)
DELETE http://example.com/collection?guid=...
GET http://example.com/collection (returns 1)
Controlling the order of items in the collection idempotently is a bit trickier, but is hopefully unnecessary in most cases.