I'm just beginning to try and understand REST design principals and have a struggle with the first example I'm trying.
Let's say that what I want to do is design a REST API to something like an SSH session. Ignoring the security, logon etc, what I was assuming is that there would be something like a /sessions URI, and I initiate an SSH session by POSTing to /sessions specifying connection information, host name, user name that kind of thing. That would cause the web server serving the REST API to initiate an SSH session on my behalf, assign it some kind of ID and return a URI of /sessions/[id]. I could then interact with that session with sub-resources of that URI. This isn't a desperately good analogy to what I'm wanting to do, but it has the essential point, that of attempting to define an interface to something that has a "session", and whose state changes as I POST things to resources within it.
Now my issue here is the scalability of it, but I can't think of anything better. It relies on the web server initiating the SSH connection with the host, and that connection has to be maintained by the web server (so would be lost if the web server had to be recycled). It also ties my request to a single web server -- I couldn't, easily, have a farm of web servers processing API requests.
I could move the creating and maintenance of the SSH connections out to another server somewhere, but that only really moves the scalability problem. And anyway, then I need to define an API to that server, and why don't I make it a REST API, in which case I've just got a duplicate of the first one, ad infinitum.
Now I may just be looking at this the wrong way, not being quite resource centric enough, but in my mind, here the "resource" is the SSH connection. My problem is that resource is not something that is easily shared -- it is something that the web server creates and is essentially transient.
Are there any RESTful API design gurus willing to help me along a better path? Note that I don't actually think that this is really REST specific -- the essential design problem would occur I imagine what ever approach I took to designing this as a web service, on the basis that web service interactions tent to be stateless.
Thanks.
[EDIT:] My other issue with this approach is the "leaking" of the "session" resources when clients don't explicitly delete them. The most sensible solution I can think of for this is to define some property of a session (maybe settable on crea开发者_Python百科tion, maybe fixed), that defines the time by which you need to contact the session again before it is considered stale and deleted. The client would access this property (say /sessions[id]/keepalive or something) which would return a timestamp, divide it by two (well take a timepoint half way between now and then) and ensure that if nothing else it "polls" the server by accessing the same resource again before that time. If it fails then the session will be reclaimed. This is the most "RESTful" approach I can think of, but would value any more experienced RESTful minds.
Usually in order to be able to declare something as a resource, it needs to be either stored in some kind of persistent storage or it should be easily reproducible. As you say a session is a pretty transient thing to try and model as a resource. It is also something that is usually tied to a single client. A resource however is normally shared, which is one reason it is assigned a public URI. All this to say you are trying to fit a round peg in a square hole.
Having said that, if you really want to do it, and you want to scale-out then I can think of two possible ways. One is to initiate the session on the single "DB" server. This would allow you to scale out the web servers. Depending on where most of the work is done, this may or may not have any value.
The other option is to take advantage of hypermedia to allow you to use the web server as the session initiator, but you need to make sure that the web server host name is part of the session resource URI. REST clients are not supposed to make any assumptions about URIs and should always read them from previous responses. If you use this to your advantage you can distribute sessions across a variety of web servers and the client just follows the URL to find the session, regardless of which web server it is on.
I think there's multiple REST issues here, some of which are because you're fundamentally trying to implement SSH over HTTP. Among the issues I see:
(1) Management of client state by server -- unless you persist the current connection (which just seems odd), you are violating the stateless spirit of REST.
(2) Funneling actions into "updates" on the connection, rather than actions on true resources. From what you describe, it appears that actions that occur on an established SSH connection would be modeled as UPDATEs to the SSH connection if you use the connection itself as a resource.
Of course, no one will throw you in jail because of how you REST-ify, but in general I do agree you're trying to fit a square peg in a round hole.
Instead, I would ask yourself why this needs to be REST-ified. SSH connections are well understood and can be done between parties in various ways without inventing what you describe. In fact, if you think about writing a GUI-based web app for your task, it seems like you are trying to implement one of those green-screen-over-HTTP solutions, which never usually have a happy ending, so I personally would avoid it.
精彩评论