You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 10 Next »

This page is meant to start as a conceptual design for a 2nd generation REST API for ESME. The idea is to learn from the discussions around and use of the original REST API.

REST API Design

Streams vs. resources

In the design below, all parts of ESME are modeled as resources, in keeping with a RESTful approach. For things like message streams, this is not an optimal way to model these entities. I'd like to maintain the ability to interface with the full ESME API in a RESTful manner, while also encouraging the use of more optimal interface approaches when this makes sense.

The existing entities called out as resources below that should be available in some manner as streams are:

  • Messages (user-specific) api/users/USERID/messages
  • Messages api/messages
  • Tags (api/tags)
  • Conversations (api/conversations)
  • Pools (api/pools)
  • Searches ??

References -
*Link to REST API 2.0 - Sessions discussion*

Methods, Resources, and Descriptions

Resource

Method

Description/Payload schema/Response schema

api/sessions

GET

(It might make sense for this to return only the current session, but in theory it would return all sessions that the current session is allowed to access, so for an administrator, it might return all open sessions. An individual session would be accessed at GET api/sessions/SESSIONID.)

api/sessions

POST

Parameters: ?token=API_TOKEN

api/sessions/SESSIONID

DELETE

or
DELETE api/sessions?session=SESSIONID (get SESSIONID from api/sessions)

api/users

GET

 

api/users/USERID/messages

GET

(get USERID from api/session)

api/users/USERID/messages

GET

(long-poll?)

api/users/USERID/followees

GET

 

api/users/USERID/followers

GET

 

api/users/USERID/followees/USERID2

POST

or POST api/users/USERID/followees?user=USERID2

api/users/USERID/followees/USERID2

DELETE

or DELETE api/users/USERID/followees?user=USERID2

api/users/USERID/tracks

GET

 

api/users/USERID/tracks

POST

Parameters: ?track=TEXT_TO_TRACK

api/users/USERID/tracks/TRACKID

DELETE

 

api/users/USERID/actions

GET

(Actions probably don't make sense outside of the context of a specific user.)

api/users/USERID/actions

POST

Parameters: ?name=NAME&test=TEST&action=ACTION

api/users/USERID/actions/ACTIONID

PUT

Parameters: ?enabled=true|false (This is actually a general outlet to update any attribute of an action, including whether or not it is enabled.)

api/users/USERID/actions/ACTIONID

DELETE

 

api/messages/MESSAGEID

GET

Gets a particular message.

api/messages

POST

parameters: message=MESSAGE_BODY&via=CLIENT&tags=TAGS&metadata=XML&replyto=MESSAGEID

api/messages/MESSAGEID

PUT

(payload the same as POST)

api/messages/MESSAGEID

DELETE

 

api/tags

GET

Return all of the tags, or user-specific tags (GET api/tags/USERID?) and let the front-end decide what to do with it.

api/tags/TAGID

GET

Gets the information about a particular tag

api/conversations/CONVERSATIONID

GET

 

One point to note is that most HTTP clients do not currently support the "PUT" or "DELETE" methods, so these have to be simulated through POST methods with an extra parameter. I think that because of the close mapping to resource verbs, is worth using these methods in the specification and defining the simulation method for the entire API separately.

Resource/Object Hierarchy

The above is based on a rough object hierarchy as follows:

  • ESME API instance (api/)
    • Sessions (api/sessions)
    • Users (api/users)
      • Messages posted by a user (api/users/USERID/messages)
      • Users followed by a user (api/users/USERID/followees)
      • Users following a user (api/users/USERID/followers)
      • Trackers belonging to a user (api/users/USERID/tracks)
      • Actions belonging to a user (api/users/USERID/actions)
    • Messages (api/messages)
    • Tags (api/tags)
    • Conversations (api/conversations)
    • Pools (api/pools)
      • ?
    • Searches ??
    • Trends ??

Each of these bullets represents a set of objects. The resource representing an individual object lives at api/objects/OBJECTID. For example, api/sessions/SESSIONID. As much as is reasonable, one would expect to be able to GET (read), POST (create), PUT (update/amend), or DELETE (delete) any individual member of each of these object sets. Going through each of these objects to ask what it would mean to create, read, update, or delete that object may reveal holes in the existing API, some of which I have filled in above.

Formats

Request formats

Format specification

If there is a request body, format should be specified using the Content-Type HTTP header.

Formats to be supported

  • XML ?
  • JSON ?
  • Multi-part Form-encoded ?
  • Form-encoded

Response formats

Format specification

Format could be specified using the HTTP Accept header - http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html

Another option (though not as robust) would be to append the format to the resource request url. For example /api/users/USERID.json

Formats to be supported

  • XML ?
  • JSON ?
  • ...

Authorization

Currently the ESME REST API uses tokens as the authorization mechanism. A token is used to establish a session and then the session is used to persist the authorization of the API client across the length of the session.

There are a couple of problems with this, though we don't have a better approach at the moment:

  1. Sessions are not natively supported in a lot of API programming environments, especially environments that do not have a persistent data-store available to the application.
  2. The current API design appears encourage that the token sent to establish the session be sent in the clear over an unencrypted connection.

Points for discussion, resolution, further work

  1. Is the use of HTTP sessions necessary? Is it desirable?
  2. Request signing methods?
  3. Payload and response schemas must be defined
  4. Should API contain admin functions?
  5. Webhooks (http://blog.webhooks.org/)
    • ESME has webhooks as part of its actions framework, but we may want to document their existence as part of the API, and possibly improve the functionality if there are use cases (http://incubator.apache.org/esme/actions.html)
  6. What is a conversation?
  • No labels