gavins
gavins

Reputation: 117

REST API Design Guideline

I am in the process of designing a public API for our REST interface. One of the thing's that came up was the use of the http verbs, specifically the DELETE verb.

We want to expose methods to start/stop or execute/abort a particular job. The two flavors of api design for these two are:

POST

http://localhost/api/campaignrun/1

Execute campaign run with an id of 1

DELETE

http://localhost/api/campaignrun/1

Abort the campaign run with an id of 1

Alternatively...

POST

http://localhost/api/campaignrun/1

{ action=execute}

Execute campaign run with an id of 1

POST

http://localhost/api/campaignrun/1

{ action=abort }

Abort campaign run with an id of 1

If have my favorite, which one is more RESTful?

Upvotes: 2

Views: 3283

Answers (5)

Genry
Genry

Reputation: 1408

As many have stated here, DELETE on a resource means that the relevant campaignrun is not accessible anymore (404 Not Found should return afterwards). My guess this is not the intention of aborting the campaignrun.

The following will be more REST compliant to any alternatives mentioned in the question:

POST

http://localhost/api/campaignruns

Note the plural noun (more RESTful, collection->instance->collection->instance...).

This request creates a campaignrun. Let's say, that the campaignrun created ID is 1.

POST

http://localhost/api/campaignruns/1/operations

{
    "operation": "execute"
}

POST

http://localhost/api/campaignruns/1/operations

{
    "operation": "abort"
}
  • The operations API support the following HTTP methods: GET, POST
  • The operations API might be implemented as async call (202 Accepted is returned).

Let's say, that the abort operation ID is 2.

Here it how it shows (assuming async operation) right after POST:

GET

http://localhost/api/campaignruns/1/operations/2

Response:

{
    "id": 2,
    "operation": "abort",
    "status": "processing"
}

Here how it should look when it is completed:

GET

http://localhost/api/campaignruns/1/operations/2

Response:

{
    "id": 2,
    "operation": "abort",
    "status": "completed"
}

Upvotes: 0

zafeiris.m
zafeiris.m

Reputation: 4489

Choosing between your two designs, I would vote for your 2nd one, that uses POST, but with a small modification: Use PUT instead:

PUT http://localhost/api/campaignrun/1

{ action: abord }

This API speaks clearly about its intentions: You have campaignruns (better keep this plural), you want the campainrun that has {id} = 1, and there is an attribute of that resource called action, which I want to update.

This way, you keep your API consistent with the idempotence of http verbs: PUT should be idempotent, POST shouldn't. For your case this means that, no matter how many times a user hits the above request, the result is the same: The campaignrun with id=1 will get aborded.

Note: I see you have accepted an answer that proposes verbs at the URIs, and then uses POST to them. This post is not a place to argue for or against REST, but since your question is about which design is more RESTful, you should think twice. You may want to check this very nice 38 page free ebook that speaks about best practices for designing APIs. Among others, it suggests to keep verbs out of your base URLs, unless very few cases. Check it out, it would prove helpful!

Upvotes: 2

matsev
matsev

Reputation: 33789

Is it possible to restart a stopped job? If so, I suggest that you use POST since you are not really deleting any resource. However, you can change the urls to better indicate what you are trying to achieve:

POST

http://localhost/api/campaignrun/1/start

and

POST

http://localhost/api/campaignrun/1/stop

Thus, there is no need for providing a request body to indicate the type of of action.

Side note: For me DELETE indicates that the campaign will be removed forever, and thus cannot be restarted. Consequently, a 404 will be returned if the client attempts to access the resource.

Upvotes: 0

Donal Fellows
Donal Fellows

Reputation: 137767

If you can use DELETE, that would be great. However, you should only do so if stopping the campaign run means that the client should never access that resource (that particular URL) again. If the client is reasonably expected to interact with the resource afterwards, use POST (or PUT to a sub-resource, of course).

Upvotes: 0

Brian Ogden
Brian Ogden

Reputation: 19232

The first is more "Restful". The only issue you will have is if you need to delete instead of abort a campaign run in the future. You can always just pass an action to DELETE if you require campaign run delete record functionality in the future.

Upvotes: 0

Related Questions