How to design a RESTful HTTP gateway for a protocol that requires persistent connections?
I'm working with a persistent client/server protocol and I need to design a RESTful gateway. I don't have a lot of experience designing REST interfaces and I don't understand how I should handle (in a RESTful way) the session IDs needed to maintain persistent connections on the server a开发者_运维技巧nd how I should represent server state as resources.
I'm asking this because I don't want to end-up with a RPC-ish result that looks "RESTful".
Problem specific context: I want to improve the existing ZooKeeper REST gateway to support ephemeral nodes and watches. An ephemeral node exists while the client is connected to the server.
Thanks.
The way in which I've done this in the past follows a "ticket" or "receipt" pattern. The REST service accepts requests for a resource (a report name, a znode, etc.) and returns a ticket. This ticket (usually a UUID or something similar) can be used to represent a session. Subsequent requests use this ticket to check on the status of their requests. To ensure proper expirey of tickets, one of two cases occurs; you can time out tickets or, upon receiving a result, the client must provide an ACK (acknowledgment) back to the service.
ex.
Request: GET /zookeeper/znode/ephemeral/foo Response: 1234-1234-1234-1234
Request: GET /zookeeper/status/1234-1234-1234-1234 Response: WORKING (or UNAVAILABLE or BLOCKED or NOTREADY or FAILED...)
Request: GET /zookeeper/status/1234-1234-1234-1234 Response: ACQUIRED (or AVAILABLE or OK or SUCCESS or some value(s)...)
Request: GET /zookeeper/acknowledge/1234-1234-1234-1234 Response: OK (or UNKNOWN TICKET, etc.)
Interesting manageability messages:
Request: GET /zookeeper/sessions (or /tickets) Response: [ 1234, 5668, ... ]
Request: GET /zookeeper/kill/ Response: OK (or UNKNOWN or FAILED...)
This has worked very, very well. This does mean, however the REST service is stateful which makes things like load balancing trickier. I've used a protocol that ensures a server ID is returned with each response and if the client receives a different server ID and an UNKNOWN ticket, you assume the service you were talking to has died and start over. This implies sticky load balancing (i.e. round-robin wouldn't work here). The REST service needs to be multi-threaded to support performing these requests in parallel and provide access to a ticket database (usually in memory, sync'd hashtable data structure) as well as a session / ticket timeout thread.
Hope this helps.
精彩评论