1

Designing an API as RESTful as possible, I wonder if it is ok to divide a resource with specific sub-URIs.

Let's have the following URIs:

  • GET /users: list users
  • GET /users/42: get detailed information about user with id=42, e.g.:

    {
        id: 42,
        first_name: "Done",
        last_name: "Joe",
        is_active: false
    }
    

I am about to consider the "is active" status as its own resource:

  • GET /users/42/is_active: get activity status about user with id=42

    {
        is_active: false
    }
    
  • PUT /users/42/is_active: set activity status about user with id=42 using as body:

    {
        is_active: false
    }
    

Any pro's or con's for doing so?

Patrick Allaert
  • 1,751
  • 18
  • 44
  • I would not go for such a design to avoid confusion for the clients. For example, what would happen in your case if user 42 does not exist, but you execute a PUT on is_active? Does it create the user? Does it throw an error? If the latter, I try to avoid this (if possible) for the sake of the 'robustness principle' -> "Be conservative in what you do, be liberal in what you accept from others". – DXTR66 Jun 21 '16 at 14:56
  • 1
    @Dr.UnitTest It would return a 404, exactly the same as if they called `PUT /users/42`. I don't agree that the robustness principle applies at all in this case. – Eric Stein Jun 21 '16 at 15:18
  • @EricStein I agree that it does not fit perfectly, but not at all? Obviously you knew what the user wanted to do -> create or fully update that resource (PUT /user/123). So why would you return an error (not found / or lets say, be conservative), just because you maybe do not want a client to select the ID of a resource (be liberal and let the client do that). – DXTR66 Jun 21 '16 at 20:01
  • But that aside, PUT was just an example. Take any other HTTP action. What would a DELETE cause on such a micro-resource? If you DELETE it, how do you have to recreate it? Is a PUT then okay? So why suddenly allow a PUT to create something? I think in most cases it will make the system more difficult (than necessary) to use, because different rules apply to 'normal' resources than to micro-resources. – DXTR66 Jun 21 '16 at 20:01
  • @DXTR66 All HTTP actions does not **have to** be supported. I don't see any difference between a `PATCH /users/42` and a `PUT /users/42/property` in the case `/users/42` does not exist and it wouldn't be different with a sub-collection like `/users/42/friends`. In this case, the allowed methods (remember that querying possible methods on a resource is possible with `OPTIONS`) would be `PUT` & `GET` only. – Patrick Allaert Jun 22 '16 at 08:04

1 Answers1

1

What you're talking about is called a "micro-resource". It's useful for doing partial updates in an idempotent manner. It's not popular in more well-known APIs, but it's certainly a valid design approach.

Eric Stein
  • 13,209
  • 3
  • 37
  • 52
  • Thanks, unfortunately, even knowing the name behind that concept doesn't help me finding resources about it. Do you have some resources to share to accredit your answer? – Patrick Allaert Jun 20 '16 at 16:45
  • @PatrickAllaert Mr. Miller metions it here: http://stackoverflow.com/a/5594376/2607240. I've spoken with other developers about it, but I'm not familiar with anything else on the internet. What specifically are you trying to figure out? – Eric Stein Jun 20 '16 at 17:12
  • 1
    I'm with @EricStein on this one. Your only alternative is to use `PATCH`, which is pretty complicated, and is not worth the effort most of the time. If you decide to use the "subresource" approach, don't forget to *link* it if you want to be RESTful. – Robert Bräutigam Jun 23 '16 at 09:44