Dan
Dan

Reputation: 12096

In a RESTful API, should DELETE calls be recursive?

Say I have the following relational structure of data (for examples sake):

A `post` which is a child of a `category`

This data can be accessed via these API endpoints:

I have now decided that I want to use my API to delete category 1 so I run DELETE /category/1.

However, category 1 has relational child post elements that can't exist without the category, would you expect this call to either fail and say you must first delete the child elements OR automatically recursively delete the child elements when you delete the category?

Upvotes: 8

Views: 2238

Answers (4)

Justinas Jakavonis
Justinas Jakavonis

Reputation: 8798

I would say it should succeed when you DELETE category.

Let's say, it fails - then you would need GET all posts and comments then iterate over them with DELETE - what's the point?

Also, I would use plural nouns for resource naming like:

GET /categories/1/posts

When getting all posts it would look more consistent.

However, it's up to you how to implement it, with or without cascading - look what better suits your needs.

Upvotes: 2

jschnasse
jschnasse

Reputation: 9498

1. Naming

  • I would use the plural form, /categories, /posts, /comments
  • in my opinion, /categories is not a good name for something that allows one to recursively delete a large number of entities from your database. I would use something like /sections, /areas or /partitions for that purpose.
  • Instead of DELETE /categories you could offer something like
  • DELETE /posts?filter=category:1

2. Routing

I would consider to use a more flattened structure for the http routes, and create independent endpoints for each entity.

Provide CR (create,read) for

GET,POST /categories
GET,POST /posts
GET,POST /comments 

Then provide RUD (read,update,delete) for the single entities

GET,PUT,DELETE /categories/1
GET,PUT,DELETE /posts/1
GET,PUT,DELETE /comments/4

In my opinion, this makes usage more intuitive and does not imply some kind of hierarchy or a certain behavior. Now define DELETE on each entity like appropriate.

3. Implementation

Example

  • DELETE /posts?filter=category:1

    Delete all posts belonging to category with id 1

  • DELETE /categories/1

    • if /categories/1 is 'empty'

      Just delete one entity of type category.

    • if /categories/1 is 'not empty'

      return a HTTP 405 Method Not Allowed and ask the user to run a DELETE /posts?filter=category:1 to empty /categories/1 first.

  • OPTIONS categories/1
    • if categories/1 is 'empty'

      set ALLOW to GET,...,DELETE

    • if categories/1 is 'not empty'

      set ALLOW to GET,... (do not allow DELETE)

  • DELETE /posts/1

    Delete the post and all comments referencing it OR use the same pattern as for DELETE categories/1

  • DELETE /comments/1

    Delete just the comment.

4. Find further information

Which HTTP status code to return when the DELETE operation is not allowed for particular reason

Upvotes: 1

Sheel
Sheel

Reputation: 845

You can able to perform these actions in Rest

"methods": [ "GET", "POST", "PUT", "PATCH", "DELETE" ],

I can able to do this thing by DELETE /categories/1/post so naming should be followed.

Upvotes: -1

smehaffie
smehaffie

Reputation: 379

IMO this is more of a design decision and their really is no wrong way to do it. So it all depends on the requirements.

If you decide that deleting a category deletes all the child post elements, then you can do that in multiple way (ordered by my preference).

  • Control that cascading deletes in the database.
  • Add code in the DAL layer so that when a category is called, it deletes all the post under the category.

If you decide to not do the "cascade" delete for the child post, then your only option is to return an appropriate error message stating why the category cannot be deleted.

If you want you can make it more clear what the call to the web service does by doing something like this.

DELETE /category/1?includePost=true --> Deletes category #1 & all post under it.

DELETE /category/1 --> Delete category #1 or returns error if it can't delete it.

Upvotes: 3

Related Questions