How do I put actions that don't match normal HTTP verbs in my API?

5,678 views
Skip to first unread message

Bram Klein Gunnewiek

unread,
Mar 8, 2013, 10:53:46 AM3/8/13
to api-...@googlegroups.com
Hello,

We are developing a REST api in which we want to perform actions on Virtual Machine instances. As an example, we might want to start, stop or reboot a machine. I don't really know how to properly model that into our API. I was thinking about something like: /machines/1/start, machines/1/stop, machines/1/reboot. Machines would be the base URL, a GET would retrieve the machine info, a POST would add a new machine, a PUT would update the hardware configuration of a machine and DELETE would remove the machine. 

I don't know the proper way to do it. In the e-book "Web API Design" its discouraged to add verbs to the base of the URL, but besides the general CRUD operations their is nothing written about verbs that don't fall into that (or I am missing the point). 

What is the best way to model these actions in our API?

Thanks in advance,

Ian Joyce

unread,
Mar 8, 2013, 11:12:10 AM3/8/13
to api-...@googlegroups.com
How about something like:

   PUT /machines/1/status
   { "status": "started" }

   PUT /machines/1/configuration
   { "configuration": "..." }




--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group and stop receiving emails from it, send an email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Clinton Dreisbach

unread,
Mar 8, 2013, 11:18:02 AM3/8/13
to api-...@googlegroups.com
Bram,

There's multiple ways to look at this. One would be to model instance actions and create them as necessary. For example, a boot, restart, or shutdown would be an action and you could POST to /machines/1/actions with the parameter or body of "boot," "restart," or "shutdown". You could also be more specific and have a boot, a restart, or a shutdown as separate resources and POST to /machines/1/boot, for example, to boot a box. One cool thing about this is that you can schedule a boot, get back its resource, and then DELETE that resource if you choose to unschedule the boot.

Lastly, you could separate the idea of a virtual machine and a booted instance. This way, you might POST to /machines/1/instances to create a running instance, GET /machines/1/instances/1 to get the status of an instance and DELETE /machines/1/instances/1 to shut it down.

Mike Kelly

unread,
Mar 8, 2013, 12:53:00 PM3/8/13
to api-...@googlegroups.com
I would model this using a non-safe request on the resource which
represents the virtual machine. This is to preserve visibility in the
request. i.e. an attempt to take some action on the VM is probably
modifying its state and therefore modifying its representation - by
addressing the interaction via its URL you are making this change of
state visible on the network to any intermediaries (e.g. cache
invalidation).

in practice this could look like this:

PUT /vm/123
{ "state": "restarting" }

You could use POST but I imagine this request is idempotent so, again,
you will increase the visibility of the request by using an idempotent
method for the interaction.

Cheers,
M
--
Mike

http://twitter.com/mikekelly85
http://github.com/mikekelly
http://linkedin.com/in/mikekelly123

CJunge

unread,
Mar 10, 2013, 10:40:47 PM3/10/13
to api-...@googlegroups.com
Here's a link where your exact example has already been done: http://kenai.com/projects/suncloudapis/pages/Home

Peter Williams

unread,
Mar 11, 2013, 4:29:51 PM3/11/13
to api-...@googlegroups.com
On Sun, Mar 10, 2013 at 8:40 PM, CJunge <camero...@sella.co.nz> wrote:
> Here's a link where your exact example has already been done:
> http://kenai.com/projects/suncloudapis/pages/Home

I prefer both the state setting via put and the new resource creation
approaches to the one taken in the sun cloud api. The verb in uri
pattern is getting pretty close to that rpc approach that we have
(mostly) become wary of.

I would choose between them based primarily on how much data was
needed. For example, if users want to be able to record a comment
about why a vm was restarted, etc, then creating a new "restarted"
resource for the vm probably makes more sense than PUTting a `{state:
"restarting", state_transition_reason: "..."}` to the vm resource
itself.

Peter
barelyenough.org

Bram Klein Gunnewiek

unread,
Mar 12, 2013, 7:45:22 AM3/12/13
to api-...@googlegroups.com
Thanks for the answers! I will use a PUT request and send the desired state I want the machine changed to. The link to the sun cloud api is very helpfull, thanks allot.

Amalendu Dey

unread,
May 3, 2013, 5:49:36 AM5/3/13
to api-...@googlegroups.com

Hamish McCreight

unread,
May 5, 2013, 1:14:03 PM5/5/13
to api-...@googlegroups.com
Hello,
 
Check out what the World Bank has done at:
 
 
Try their API Query Builder at bottom of page.
 
Regards
 
HMC

Glenn Block

unread,
May 5, 2013, 2:47:40 PM5/5/13
to api-...@googlegroups.com
I recommend modeling those "actions" as separate resources which you then POST to. I usually try to still name those as "nouns" i.e. approval vs approve, but that's just a preference. If you read the HTTP spec, POST can basically mean anything, so it fits.

i.e.

POST orders/100/approval
POST account/100/creditCheck
POST process/fulfillment/start


--
Reply all
Reply to author
Forward
0 new messages