RE: REST Design Question #5

Wherein I respond to Dave Megginson’s last REST design question.

Dave’s strawman notwithstanding, there’s nothing necesarily unRESTful with using XML-RPC-encoding, SOAP’s rpc/encoded, RDF, TM, “doc/literal” domain-specific XML as the representation encoding. I’d argue that … in terms of RESTfulness … the most transparent, visible, unambiguous and resiliant formats are the best, but maybe that’s just me … a quick re-reading of Dr. Fielding’s dissertation about representations doesn’t constrain the formats.

As well, I would agree that a bottom-up standardization of useful literal-XML patterns is a good thing; anything to save us from more data- and content-type XML encoding; as Tim Bray said recently, “[...] it would appear that it’s more valuable to know what something is called than to know what data type it is. That’s an interesting lesson.” Don’t get me wrong, being able to trivially [un]serialize data-structures on the wire is useful. It’s may be just not the best way to go about building internet-scale services. What if your language doesn’t have unsigned types, for instance? Or you try to serialize to me a super-complex data-structure that my platform simply has no implementation of? I believe it’s better to let [the client] handle how I’m going to store data, and let us exchange literal- rather than encoded- content.

In any case, I would argue (and I have been increasingly, recently) that “REST” is the wrong marketing word for what you’re really talking about. I believe what you’re calling “Amazon, EBay’s and Flickr’s ‘RESTful’ Web Service APIs” are in fact not [necessarily] RESTful … I think it’s better to characterize them as SHARE — Simple HTTP API via RPC and Encoded data.

So, yeah, REST continues to be an architectural style. For a variety of reasons, the word REST has been co-opted to describe not-necessarily-RESTful things … SHAREd and SHARE-friendly APIs, specifically. Please join me in tilting against windmills^W^W^Wtrying to call things by reasonable names.


So, now, maybe Dave will entertain a question I have.

RESTafarians boast that there are RESTful web applications already online for Amazon, , eBay, Flickr, and many others, but developers quickly figure out that they don’t get any benefit: each REST application requires its own separate stovepipe of code support right from the ground up, because they all use different content formats. If these all used XML-RPC or SOAP, there would be many standard libraries to simplify the developers’ work, and a lot of shared code that could work with all these sites.

Is the bit that’s shared across all these sites the XML <-> object mapping only, or something more? What else are you thinking of? For bonus points, why are XML-RPC or SOAP required for those things to be librarized?

unintentional fail-safe messages

The Bluetooth audio-receiver in audio-casette form-factor that’s been making the rounds on the gadget-porn sites today is kinda cool; My First RedBox was in a modified audio-casette case, so I understand the appeal … but, seriously, who has an audio-casette deck anywhere anymore? If you’ve got a $500 bluetooth-capable digital audio player, you’ve probably swapped out your car’s crusty tape deck for $50…

In any case, that’s not important right now. What is important is that you carefully read the small text at the bottom of the casette…

First, read the left-side text, and note that – while slightly strange – it’s basically coherent, and an important instruction! Now, read the right-side text and realize that it’s supposed to be read straight across. I can’t believe that it was intentional that the left-side text is a stronger assertion than the text as a whole … i.e., if you only read the left you wouldn’t even glance at the screw, but when you read the whole thing you understand that you’re allowed to. With different wording and line-breaking, it may have resulted in something entirely less safe.

RE: REST Design Question #4, part 2

In response to Dave’s update…

Responding to the RDF bits, I guess RDF/XML makes what you’re trying to express a bit more verbose, but it’s hard to call it difficult. It’d end up being…

John Hughes

…with ‘director’ as an rdf:type, and ‘name’ being the property/relation to the subject “12345.html”; or, in Turtle/N3…

<12345.html> a :director; :name “John Hughes”.

I’d recently worked out a different XML serialization — http://asynchronous.org/rx/ — for RDF that is a little more concise for data that’s mostly properties, and not so much about rdf:types. It also does not allow mixed-content, but it doesn’t require node-typing and thus element-striping; it would allow you to say…

John Hughes

… though that would result in the Turtle…

<12345.html> :director “John Hughes”.

Frankly, I like the version with “name” involved better, but it’s your data-model. :)


In any case, I see a bit more how this is specifically about REST, but I’d still argue that it’s more about change-handling in coarse-grained API design. If in a [local] procedural approach you may have…

Film.setName( String newName ); Film.setYear( int newYear );

… the argument goes that in a remote-procedural environment you should really, and only, just have …

updateFilm( Film newFilmData );

… to cut down on network round-trips, update overhead, synchronization/coherency concerns, &c.

So there is an interesting issue about how much of a representation — either the whole representation or just the changed aspects — need to be given back to the server. I guess it’s really a function of the server’s capabilities, as well as an assessment of the client’s capabilities, as well as what’s reasonable for the application/API.

Back to a “RESTful” worldview, one way to go is simply say “PUT back the whole representation”, which as you’re saying can be weird. Reasonably, the server may ignore [either silently or loudly] changes to some fields. An optimization of this may be to used something like RFC3229 to be more … um … optimal.

Another way to go would be to put something inline in the representation — either a form or indiciation that a certain convention is supported — that effectively says to the client “hey, you only need to send changed fields on update” or “here are the change-allowed fields” or something.

I’d consider these both RESTful, since both are talking about a constrained interface, placing the semantics in the media-type and document content, and using hypermedia as the engine of application state. The former certainly implies more server- and client-side smarts, and the latter is certainly what the web does. I guess if I were trying to be pedantic, I would call the later more RESTful, since the server is directing the client about how to proceed …

… but this is also the point I start to get into trouble about RESTful API design. In traditional RPC/RMI environments, the client is built with a specific understanding and knowledge of the API space. In the web, a human sits just past the client-side UserAgent, and interprets the generic HTML and forms that come back. I believe there is an intersection of those two, but I’m having trouble finding it.

RE: REST Design Question #4

Dave Megginson’s 4th REST Design Question

  • I don’t see how this is REST design question in particular.
  • I think questions and concerns like this are why a number of RESTafarians are also RDF-heads.

I think the ultimate response to this question is: Do The Right Thing for your clients. If you anticipate them needing to see “John Hughes” in order to make a determination about whether to traverse the associated subject-URI^W^W^Wxlink:href, then do so. But it’s just generic information- and API-design questions at this point.

jyWebShell

After my efforts Friday to get jython working in swing, I set upon my real goal: HTTP/HTML access to a server-side jython session. The idea is that the jython session runs in the app-server container, and thus has access to the full runtime configuration and capability of the system. It is exposed to the user[s] in a durable yet dynamic manner.

I’ve packaged up the results as jyWebShell 1.0. At 5MB, it’s a bit larger than a traditional .war file since it contains the full Jetty distribution, as well as Struts and jython.

I use the XMLHttpRequest object in the UI, which submits just the current python command, and updates the page in-place with the result of that evaluation; however, if the XMLHttpRequest doesn’t exist, a normal POST is done, and will work just fine.

I’ve also got a short Flash demo [read: "screencast"] of it in action; no audio, unfortunately … a project for another weekend.

allowing trackback

I’m now allowing trackback by default on new posts. Since this (and syndication-feed generation) was my original motivation for moving to MT (vs. a homebrew/ad-hoc setup), I feel kinda silly. In my defense, I know what “ping” is, and it’s not “trackback”. Now I know what “moveabletype:ping” means, too. :p

REST Design questions 2 and 3

Dave Megginson continues with his REST design questions. Herein, I respond:

Question #2

Yup, I’ve used query-paramaters in the way you describe to paramaterize a large resource space. I don’t consider it particular inelegant or ugly, but maybe that’s a matter of perspective…

I believe that retrieving the “container” resource should respond with a form, indicating something like … “the resource is large, and supports paging, and the following values can be used to paramaterize the resource-space: * offset:non-negative integer * count:bounded integer:0..50 * sortCode:enumeration{ * ‘name’: ”’sort on object’s name”’ * ‘size’: ‘sort on object’s size’ * …} * sortAscending:boolean “

As HTML has its forms, we probably want media-types tailored to machines … either a new level of user-agent mediating for the user, or an autonomous one.

One of the more annoying issues I’ve run into with this is documentation of the cross-parameter interaction of complex query-spaces. Once things become a flattened name-value-pair list, I don’t believe you actually lose representational complexity (vs. submitting, say, a QueryParam struct on a more traditional procedural API), but you definitely lose representational ease. You may have to do things like lexically-structure your paramater-names, or disambiguate them. That bit is pretty inelegant, true.

Question #3

Links means whatever is specified by the format defining the context in which link appears. For instance, html:a@hrefroughly means “this is the the location that should be travesed to in the user agent when the contained object is clicked on”, or something. In the @xmlns case, yes, it does not mean what html:a@href means, but why should it?

And, yes, while the URIs which are used for most xmlnses don’t resolve, this is a bad thing, specifically for the reasons you’re getting at — HTTP URLs should resolve. This is especially true for namespaces, IMHO, because more often than not the semantics are implicit and unknown, unlike HTML where it’s expliclit and well-known.

Yes, there’s some nice ideal world where a spider can simply GET deeper and deeper into information resources. And in a RESTful web, that may even be very true. But it’s a bit naive to believe that at some depth the crawler doesn’t need to understand a least a bit of the document semantics — in fact, an important part of Fielding’s dissertation is that the HTML semantics are wide-spread and well-known.

simple swing jython shell

Today I created a little swing GUI shell to provide an interactive session with a Jython interpreter. It comprises two text areas — a larger area at the top for output, and a smaller text area at the bottom for input. It is not line-level interactive, as the normal console shell is; instead, you submit complete expressions with Ctrl-ENTER.

There’s a bit of trick in there about two different methods on the PythonInterpreter API: exec and eval. Digging through the sources of the provided interpreters, I came up with the following, which seems to work well:

cmd = input.getText(); output.write( “>>> ” + cmd + “\n” ); try { res = interp.eval( cmd ); output.write( res.toString() + “\n” ); } catch ( PyException exec ) { if ( Py.matchException( exec, Py.SyntaxError ) ) { try { interp.exec( cmd ); } catch ( PyException exec2 ) { output.write( exec2.toString() ); //exec2.printStackTrace( new PrintWriter(output) ); } } else { output.write( exec.toString() ); //exec.printStackTrace( new PrintWriter( output ) ); } }

Here is the whole swing jython interpreter shell program; compiled against Jython 2.1,

Re: REST Design Questions

Dave Megginson has posted some questions about his understanding of REST.

First off, please do look beyond the “there are only 4 [HTTP] verbs” aspect of REST. “Hypermedia as the engine of application state” is hand-in-hand with Constrained Interface as being fundamental to the RESTful web. As well, the GET/POST distinction is critically more important than any other aspect of constrained interface, I believe.

Back to question 1 … yes, the identifier does need to be recorded. This is the client’s responsibility, though a good server would help. That is: if the usage of the protocol is embracing REST, then each message would already come back with the identifier of the resource baked in. In any case, I think there’s a fallacy that the resource representation alone is or should be solely sufficient to describe the resource … if that was the case, why does HTTP need headers at all!? Certainly, there is meta-data that the client must be responsible for.

On the client side, I think your options are: keep the data external to the representation, or keep it within the representation. Since you’re assuming XML documents, I recommend that you use it’s extensibility, maybe via a namespaced attribute on the root level. How about thisDocumentWasHttpRetreived:from="http://.../", or maybe rdf:about?. I’ve also used [eg:]href, which works well; you may like xlink:href, though.

Regarding identifiers and locations … it’s nice to know the identitiy of things; it’s also nice to have locations of things. But it’s really nice when your Uniform Resource {Identification,Location} scheme supports redirection, such as HTTP[s] does.

Amazon’s RESTless WS API

Steve Maine’s Isomorphism post is really good until the end, where he tries to make a point about Amazon.com’s “touted” RESTful web service API.

The REST crowd touts Amazon’s human-focusedservice as a REST example, not the WS API.

Only Amazon themselves claim that their non-SOAP API is RESTful, and I believe it’s because they’re confused. As well, there’s not a marketing term for “simply using HTTP query strings to invoke RPC which returns XML without doing SOAP or XML/RPC”. Thus, everyone calls it REST, even though it isn’t, necessarily.

So, the reason that <wsa:Action>urn:GetCart</wsa:Action> and http://webservices.amazon.com/onca/xml?Operation=CartGet[...] are isomorphic is because they trivially are. They’re both RPC.

Re-creating the same thing in a purely RESTful way would not look isomorphic, depending on how much of HTTP you want to exploit. I’ll leave that as an exercise for the reader, for the moment. As well, Joe Gregorio has been developing that idea out.