dadads
dadads

Reputation: 201

RESTful data structure patterns

I tried Googling and searching everywhere, but couldn't find a definitive authority on this topic. While being true to REST principles, how should I design the HTTP interface for:

  1. An ordered list (get, add, insert into position, reorder, remove)

  2. A set (get, add, remove)

  3. A hash-table (get, add, remove)

NOTE: These data structures are to contain references to existing resources with known ids

Upvotes: 7

Views: 2338

Answers (5)

ioseb
ioseb

Reputation: 16951

@dadads

You can not define such interface directly.

An ordered list (get, add, insert into position, reorder, remove)

By excluding "insert into position" and "reorder" you can perfectly implement "get", "add" and "remove" for example:

  • You define your resource /service/users
  • You can use POST /service/users to add new user to the "users" collection
  • You can GET /service/users to retrieve users
  • You can GET /service/users/user-id to retrieve particular user
  • You can DELETE /service/users/user-id from users collection

This is a very rough example, though it outlines some ideas. In order to achieve "reorder" and "insert into position" you need to implement your own action semantics which you can include in your resource representation and let client know HOW to perform these operations. As a reference you can see this JSON PATCH specification proposal: https://www.rfc-editor.org/rfc/rfc6902 which tries to describe such operations.

It is not necessary to use already existing media format, you can define your own under your own namespace for example: application/vnd.your-company.format-name+json which describes these capabilities and also advertises this information to clients.

Upvotes: 2

richard
richard

Reputation: 12498

I came to this question mostly looking for a RESTful way to reorder. I don't really like any of the answers, so here is what I think is most RESTful.

For reorder you could make the order a resource:

/list/order

Then you can do normal operations on it (for these examples assume a list with 5 items currently in it):

"items":" [
     {
         "id": "A",
         "name": "Monkey"
     },
     {
         "id": "B",
         "name": "Cow"
     },
     {
         "id": "C",
         "name": "Horse"
     },
     {
         "id": "D",
         "name": "Turkey"
     },
     {
         "id": "E",
         "name": "Tasmanian Devil"
     },
]

Note that "order" is not included in the resource response. It's not needed - the order is implicitly specified by the response order of the items.

GET /list/order

returns a list of item ids in their correct order

['A','B','C','D','E']

POST /list/order with payload ['D','B','C','A','E']

GET /list/order

returns a list of item ids in their correct order

['D','B','C','A','E']

Also obviously you would return the items in the list in the correct order when you do a GET on /list.

GET /list

returns a list of items in their correct order

"items":" [
     {
         "id": "D",
         "name": "Turkey"
     },
     {
         "id": "B",
         "name": "Cow"
     },
     {
         "id": "C",
         "name": "Horse"
     },
     {
         "id": "A",
         "name": "Monkey"
     },
     {
         "id": "E",
         "name": "Tasmanian Devil"
     },
]

Upvotes: 0

ming_codes
ming_codes

Reputation: 2922

This is my idea for reordering.

There is a HTTP method called PATCH that is used to update fragments of a resource. Give your resource a new property called index, then make a call with PATCH method

PATCH /collection

[
  {
    "id: "original index 0"
    "index": 1
  }
  {
    "id: "original index 1"
    "index": 0
  }
]

Then your server back-end needs to figure out how to do this atomically. But interface-wise, I think this is the best way to stay true to RESTful.

Alternatively, there is a better solution, but it may not apply to everyone's case. Since ordering always depends some sort of criteria, it can even be as simple as insertion order. Let your collection url support an orderBy query string, and let this orderBy dictate on how the result gets ordered. Then during your reordering call from client, just update the resource's property used for the ordering criteria.

Upvotes: 1

Brady
Brady

Reputation: 10357

You should decouple the transport mechanism from the underlying application. I would consider designing the application correctly, then figure out how to access it via HTTP. This way you could easily add or change the transport mechanisms (SOAP, SCA, etc) without affecting the underlying application.

Once you have the application correctly designed, consider accessing it from the HTTP requests via something like an Adapter or Visitor pattern.

Upvotes: 1

laurent
laurent

Reputation: 90766

That's how I would do it for an ordered list and hash table. I guess the methods would be the same for a set and a list:

Ordered list

Get item 123:

GET /list/123

Append an item to the list:

POST /list/

Insert new item into position 5:

POST /list/?position=5

Move item 123 to position 3:

PUT /list/123?position=3

Delete item 123:

DELETE /list/123

Delete item at position 3:

DELETE /list/?position=3

Of course, your API should update the indexes of all the elements when doing insertion and deletion.

Hash table

Get item "somekey":

GET /hashtable/somekey

Add item "somekey":

POST /hashtable/somekey

Remove item "somekey":

DELETE /hashtable/somekey

Upvotes: 10

Related Questions