REST API design for non-CRUD actions, e.g. save, deploy, execute code

rest

Resource in my REST API context is application code written in some programming language. CRUD operations that can be easily mapped to HTTP verbs are save/edit/delete code. Non-CRUD operations that are difficult to map to HTTP methods are deploy the code on server, execute the code, and undeploy.

Common suggestions I came across in SO are:

  1. Restructure the action to appear like a field of a resource, e.g. if your action is to activate an engine, design URI: PATCH engines/123, body: {"status":"active"}
  2. Treat the action like a sub-resource, e.g. PUT engines/123/active without a body
  3. Use query parameters, e.g. PUT engines/123?activate=true
  4. Be pragmatic and go for a non-RESTful, RPC-style URL, e.g. PUT engines/activate?id=123

I am definitely not able to fit deploy/undeploy/execute code actions to a resource as suggested in #1 and #2. Could you please share your opinion how best we can design the APIs for these actions?

Best Answer

Could you please share your opinion how best we can design the APIs for these actions?

Create/Update/Delete information resources, and as a side effect of that, do work behind the API.

So think documents.

One very good example: In RESTful Causistry, Tim Bray asked about an api to shut down a machine. Seth Ladd's response, in particular, is important to read

Fundamentally, REST is a bureaucracy that solves problems with paperwork. If you want to get anything done, you submit the right form; which becomes an information resource describing what you want done.

PUT /deploymentRequests/abcde

Please find the artifacts from build 12345 and deploy that artifact
to machine 67890

201 Created

The request is just a document, in exactly the same way a sticky note on your desk asking you to address some task is a document.

As far as REST is concerned, the spelling of the URI absolutely does not matter; but from the point of view of a human readable naming convention, start from the fact that the resource is the document -- not the side effect that you want the document to have.

So, for example, it's totally normal and compliant with REST that the document that describes the current state of a thing and the document that describes changes you want to make to a thing are different documents with different identifiers.