akuchlin@... wrote:
>
>...
>
> REST version:
> GET master/list_services
> Returns a list of services as the body.
> XXX should the optional 'application argument be a URL parameter? Then
> you'd do "GET master/list_services;scope" to get all the microscope
> services. Or should it be the query string?
Good question. I think that the answer is:
* URIs are mostly opaque. This gives you tremendous flexibility as an
application designer. If you relate to resources through a URI then you
could actually move one resource physically to another mean and just
update the link.
* ;-parameters are opaque. So if you use them, you are saying that
client software should NOT understand what the stuff after the semicolon
means.
* ?-parameters are not opaque. You're saying that it's okay for the
client to try to understand tha part of the URI and fiddle with the part
after the ? mark.
Practically speaking you could use "?" if you want to allow an HTML
forms client to work with this stuff. That's a way of thinking through
whether you mean for it to be opaque.
> XXX how should the returned result, which are (service ID, application
> ID, host, port) 3-tuples, be encoded? As an XML-RPC array of structs?
> As a little custom XML schema?
No real advice. Depends on whether you are trying to make life really
easy for the client (xmlrpc.decode()) or whether you want to have other
people elsewhere on the Web support your little "schema" (in which case
a formal definition woudl be better) and whether you think message
self-descriptiveness is important or not. A merger might look like:
<array role="service_description"><int role="id">..</int><int
role="host">...</int>...</array>
Costs and benefits to everything. Also consider an element with three
attributes. Compact, very readable and trivial to work with in a DOM.
But then again, maybe this resource should just be *hyperlnks* to the
services. You could have an optimized "report" sub-resource for fetching
batch data, but I like the idea that Matisse server could incorporate
services described on other people's boxes just by reference. Part of
the benefit of REST. You might not take advantage of it but another
Mattise interface implementor might. ;) Build a web of Matisse's!
> \begin{methoddesc}{get_service}{service}
> Returns a struct (= a Python dictionary or a Java \class{Vector}
> instance) with information about the given service. The contents of
> the struct are explained below. \var{service} is a string containing
> a service ID.
> \end{methoddesc}
>
> REST version: GET master/service;service ID. Returns an HTTP body,
> encoded using the same schema/form as list_services().
I'd use "/" instead of ";" to indicate hierarchy but it doesn't matter
much.
> Interface: Login
>
> \begin{methoddesc}{get_service_ticket}{user_id, password, service_id}
> If the user ID and password are correct, returns a string containing a
> ticket for the given service. If they're wrong, it will raise a fault
> with the fault code 1 and fault string ``IncorrectPassword''.
> \var{user_id}, \var{password}, \var{service_id} are all strings.
> \end{methoddesc}
>
> REST version: POST master/get_service_ticket. This must be HTTP
> authenticated with the username (meaning a human-friendly ID as
> opposed to a URI?) and password. The body is the service ID. Returns
> an authorization ticket as the body.
> XXX should the service ID be specified as a query string?
> XXX or should this be a subset of the service's URI, so you'd access
> master/(service ID)/get_ticket, instead?
Yes, I like this latter one. *BUT* /-separated URIs are opaque so to be
REST-y you need to have service_ids point to their ticket granting
components. The client shouldn't just paste together the URI. Once again
the virtue is that you can put the ticket granting component on any box
on the Web. Plus spiders can follow the links but not guess your URI
conventions.
Should the ticket be a resource? Here's are arguments in favor: the
client can DELETE when it is done with it. When we add notifications to
HTTP, the client could WATCH it to see if the server DELETEs it because
the client is kicked off or something. A client that is kicked off could
do a GET to see if the authorization ticket disappeared or was just
replaced.
Of course, like anything, you need to decide when more REST is more
effort for not enough gain.
> Interface: Authorization
>
> \begin{methoddesc}{check}{user_id, service_id}
> Returns a Boolean value. Returns true if the user \var{user_id}
> is permitted to access the service identified by \var{service_id}.
> \end{methoddesc}
>
> REST version: POST master/check_auth
> XXX how should the two parameters be passed? (XML-RPC again?)
Why not query params?
I notice you have multiple top-level URIs. I think you should have a
Matisse.xml which is a tiny vocabulary that points to them for the URI
opacity reason I've given before. One day you may move some methods off
for load reasons or something and you can do that by just redirecting a
URI. Plus this is a simple form of interface introspection.
> Interface: MetadataStore
>
> \begin{methoddesc}{get_cache_location}{ticket, metadata}
> \var{ticket} and \var{metadata} are both strings. Returns a string
> containing an FTP URL; the data should be stored to this URL.
>
> (Rationale for choosing FTP: it's standard, it seems hard to improve
> on it for shipping data at high speed, and the DPSS code supports it.)
> \end{methoddesc}
Does anyone use "NETBLT"? Someone pointed me at it a few months back.
> REST version: POST master/get_cache_location. The body is your
> authorization ticket. The returned body is the new URI for the data
> time. HTTP PUT the content to the URI to store the data; HTTP PUT the
> metadata to URI/metadata to store it.
> XXX what if you crash after getting the new URI? You now have an empty
> resource. Can this all be done in one HTTP operation?
Sure. Shove as much data as you want down the POST. Maybe it's mildly
non-HTTP-ish to create two resources with a single POST but it is very
mild. If you want to be a purist, use HTTP POST and then a PUT for the
metadata. Have the data time URI point to its metadata.
Method names that start with "get_" bother me because they seem RPC-ish.
Ones that start with get_ and do a POST kind of freak me out. ;) Maybe
generate_data_time or something. Why is this a POST at all instead of a
GET (perhaps dynamic)?
> Interface: MetadataSearch
>
> \begin{methoddesc}{search}{ticket, condition1, condition2, ...}
> Returns a list of metadata IDs that match all of the given conditions.
>
> ... full description deleted ...
> \end{methoddesc}
>
> REST version: No equivalent is attempted. You could let Google crawl
> the URIs for your data, build RDF or topic maps or whatever you like.
> This interface goes away and is replaced by the panoply of search
> technologies available for the Web.
ZEN!
Of course you can always provide a search facility if you want using
query params. There's nothing wrong with it if you can implement it more
efficiently server side.
> Interface: Preferences
>
> \begin{methoddesc}{get_preferences}{ticket, service/application}
> Retrieve a string containing preferences information.
> \end{methoddesc}
> \begin{methoddesc}{set_preferences}{ticket, service/application, prefdata}
> Store the string \var{prefdata} containing preferences information.
> \end{methoddesc}
>
> REST version: easy! To get preferences, POST
> user-URI/prefs/applicationID, passing an authorization ticket as the
> body. To set preferences, PUT to the same URI, passing the preference
> data in the body.
If authorization tickets are resources then you can do a GET of the same
form as this:
user-URI/prefs/applicationID?URI_encoded_authorization_URI....
GET and PUT go nicely together. ;)
Paul Prescod