3

I am still trying to wrap my head around certain cases in REST where using resources defined by names instead of verbs is less intuitive than in simple CRUD cases.

I have an "Update" resource, for updates/addons of the backend, with a Json representation as follows:

{
  "id": 1,
  "name": "Update Example",      
  "description": "demo update , adds handling of basic arduio type devices",
  "version": "0.0.4",
  "link": 
  {
     "rel": "self",
     "uri": "http://demo.org/updates/1",
     "type: application/json"
  },
 }

EDIT: To clarify things a bit following Darrel Miller's answer: an updates "Updates" collection resource is already in place and it works like this:

  • The back-end populates that collection based on a list of updates fetched (via polling) from an external server (that does not use rest, the update descriptions there are minimal, and pure text)
  • The user using the API cannot add updates, all he can do is get the updates list, and install/ uninstall them

Now the problem is this:

I need to find a proper, restfull way to install updates via the API, and I came up with a few ways to do this, but they all seem "not quite right" to me:


1- Add a link to the Update resource, add an Installation resource and make use of hateoas

Add this to the update:

   "link": 
      {
         "rel": "Installation",
         "uri": "http://demo.org/updates/1/installation",
         "type: "application/json"
      }

Installation resource :

  {
       "installing": false,
       "installProgress": 0,
       "link": 
       {
         "rel": "self",
         "uri": "http://demo.org/updates/1/installation",
         "type: "application/json"
       }
     }

To start the installation process the user would then POST to demo.org/updates/1/installation to update "installing": false to "installing": true

This seems like it would work but is it good practice to add the "installing" as a simple boolean attribute?


2- POST to a uri like demo.org/installations , to add a new Installation resource

Thereby starting the install process, and also requiring the addition of a link to the update being downloaded inside the newly created Installation resource :

 {
   "installProgress": 0,
   "link": 
    {
       "rel": "update",
       "uri": "http://demo.org/updates/1",
        "type: application/json"
    },
   }

While this may centralize the Installation resource logically into an Installations collections, my original reflex would have been to DELETE an item in this collection to stop its installation .

In that case if the Installation resource instance is gone , would the use of the "installation" link on the update have to recreate a new installation resource every time it is "navigated" ?

More generally, would it not be better to have an "installed" attribute in the Update itself to make sense overall ?

Also what if the user wants to pause something like an installation ?


I have looked at a lot of similar questions in various articles and here on stackoverflow, but i still am not quite sure what the best way to tackle these kinds of problems is. Also , I know REST is not about verbs (beyond the HTTP ones) but I still believe this is a valid question.

So please, any feedback is very welcome !

Thanks in advance.

Community
  • 1
  • 1
Mark Moissette
  • 169
  • 2
  • 13

1 Answers1

4

How about if you POST to an "Updates" collection resource. That would return a 202 with a Location link to a "Installation" resource that is transient. When the installation finishes it would contain a link to the deployed "update" resource. At some point you can garbage collection the installation resources.

So for me, intuitively you would add an update to the updates collection and if you wanted to see previously installed updates you could GET this collection. Operations that are available purely during the installation process, like pause and cancel, they can be made available as links in the "installation" resource.


Update:

Ok, so if the user cannot POST to /updates then another approach is to create a processing resource called "Installer".

POST /Installer
201 Created
Location: /Installation/345

The pause and cancel terms are what I would use for the rel. Nobody should give you a hard time for that. What URI you use for those rels is a bit more tricky. Cancel could definitely be done by deleting the installation resource. Maybe you could do pause by doing a PUT to /installation/345/status.

To implement those additional actions will almost certainly require creating some other kind of resource/sub-resource. That's fine. In my opinion you should never hesitate to create a new resource if it is a simple solution to your problem. We only have the HTTP methods to work with so modelling complex behaviour requires us to get creative with new resources.

Darrel Miller
  • 139,164
  • 32
  • 194
  • 243
  • Thanks for the fast answer Darrel ! I think i should have been clearer on the updates collection resource so i edited the question accordingly. Basically that collection resource already exists, and the user cannot not POST to it to add an update (see edit). However perhaps I could use your method (I do like the idea of having that POST return a link to a transient "installation") but by separating installed vs not installed resources: ie when installing a new "update" , post to _demo.org/newupdates_ instead. – Mark Moissette Oct 08 '11 at 08:34
  • I like the second part of your answer aswell, having links to pause and cancel inside a transient resource fits the idea of them only existing within the confines of the "Installation" state. But basically would I not be "cheating" by considering pause as the noun "a pause" (borderline nitpicky , but might be frowned upon) ? Does this also not lead to a multiplication of sub resources that are almost nothing but boolean ? – Mark Moissette Oct 08 '11 at 08:45
  • Thanks once again, I think I will validate your answer since it is as close as it gets ! Ironically, it is quite similar to one of the solutions I tried , with an additional resource that was called "UpdateStatus" etc . I wanted to simplify it to avoid un-needed complexity , but I guess that there are no "miracle solutions" for such cases in REST,and as you say, it requires some "creativity" as far as resource go:) – Mark Moissette Oct 12 '11 at 08:23