2

What is the de-facto/conventional practice when enforcing business logic in a REST API and what HTTP Status Codes are used?

For example, lets say that I have a Player entity and a Team entity. A Team can have any number of players.

Let's say that my business logic (currently) prevents a Team from being deleted until all of the Players have been explicitly removed from the Team first.

If you execute a

DELETE http://api.foo.com/teams/15

and it still has Players associated with it, would you return an HTTP 409 (Conflict) or an HTTP 412 (Precondition Failed)? 412 seems more logical because I prefer to use 409 for indicating optimistic locking conditions.

Or perhaps - should that business logic condition even be enforced at all in a REST API? That is, if someone executes

DELETE http://api.foo.com/teams/15

shouldn't that just remove all Players and then delete the Team automatically? Is it more conventional to allow the DELETE to execute as the REST API can be perceived as a little 'lower level' or more 'raw' than UI interfaces?

Finally, what about a query param to in the Resource URI:

DELETE http://api.foo.com/teams/15?force=true

which indicates, "Yes, I know that this wouldn't be allowed with players still on the team, but do it anyway".

The idea here is that deleting a Team can be a heavyweight operation with significant repercussions and you only want to do it if the end-user is really sure they want to.

In other words, how much hand-holding do you do (employing 'are you sure?' error codes) or do you just execute it without any check? I'm not quite sure if this should be enforced only in the UI or in the REST API or both. How do most people solve this today?

Les Hazlewood
  • 18,480
  • 13
  • 68
  • 76

3 Answers3

4

The client tried to do something that for business reasons was not a valid request. Therefore, I would use 400. Use the ReasonPhrase/entity body if you want to communicate additional details.

Darrel Miller
  • 139,164
  • 32
  • 194
  • 243
2

412 would be incorrect in this case since this is based on evaluation of request-header fields (see this question for when to use HTTP 412). The correct status code here would be 403 Forbidden — i.e. request understood, but refusing to do it, and authorization will not help. You can provide more details to the client in the response body.

As far as whether the business logic should even be implemented, that's entirely up to you. You may even choose to implement that sort of check based on ACL — for example, certain users are only able to DELETE the team once all players have been deleted, and admins can DELETE teams regardless. A non-admin user making a DELETE request for a team with players should now return a 401 Unauthorized (i.e. the action was refused for those credentials). Admin users would get a 200.

EDIT: More information, as always, in RFC 2616.

Community
  • 1
  • 1
cmbuckley
  • 40,217
  • 9
  • 77
  • 91
-1

The cases I have worked where REST service hosted on lotus notes, if we need to delete any entry from lotus notes, we mandated to set 'confirm/force' true parameter, just to make sure invoker (UI/REST Client) are aware of deletion. If your service is REST service, I think having at UI level is not quite enough, we need to have same constraint in REST URL also.

I haven't encountered any scenario like you mentioned (delete team should delete player), but I would lean more towards 412 code in this particular case.

kosa
  • 65,990
  • 13
  • 130
  • 167