2

This question is related to a simillar one posted on RESTful design: when to use sub-resources? but it doesnt mention this case.

I have this example

/cars/{carid}
{
"id": 1,
"brand": "something"
"engine":
{
"horse_power": 100,
"type": "hybrid"
}
}

What would be a proper reasoning that could help me decide if this example should be split into a sub-resource to look like this

/cars/{carid}
{
"id": 1,
"brand": "something"
}

/cars/{carid}/engine
"engine":
{
"horse_power": 100,
"type": "hybrid"
}
Community
  • 1
  • 1
mko
  • 6,638
  • 12
  • 67
  • 118

1 Answers1

2

Maybe splitting the main resource into multiple sub-resources makes sense if the main resource is a complex entity with many arrays and other related entities.

However, if you are concerned about performance issues, bear in mind that premature optimization is the root of all evil. You shouldn't optimize until you have a performance problem and you have proven that the performance problem comes from sending a large representation of the resources.


For the situation mentioned in the question, supporting a sub-resource like /cars/{id}/engine could be useful when replacing the whole engine of the car, as following:

PUT /cars/1/engine HTTP/1.1
Host: example.org
Content-Type: application/json

{
  "horse_power" : 110,
  "type" : "eletric"
}
HTTP/1.1 204 No Content

When requesting /cars/1, a full representation of the car, including the engine, would be returned:

GET /cars/1 HTTP/1.1
Host: example.org
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json

{
  "id" : 1,
  "brand" : "something",
  "engine" : {
    "horse_power" : 110,
    "type" : "eletric"
  }
}

To return a partial representation of the resource, consider the approaches mentioned in this answer.

When requesting /cars/1/engine, the representation of the engine would be returned:

GET /cars/1/engine HTTP/1.1
Host: example.org
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json

{
  "horse_power" : 110,
  "type" : "eletric"
}
Community
  • 1
  • 1
cassiomolin
  • 124,154
  • 35
  • 280
  • 359
  • But this would also be possible with PUT /cars/1/HTTP/1.1 Host: example.org Content-Type: application/json { "horse_power" : 110, "type" : "eletric" } – mko Feb 22 '17 at 14:58
  • I was looking for more rest related benefits when splitting resources other then cleaner code and less markup. – mko Feb 22 '17 at 14:59
  • @mko When performing `PUT /cars/1`, you are expected to replace the target resource (in this situation, the car with the ID `1`) with the representation sent in the request payload. – cassiomolin Feb 22 '17 at 15:00
  • exactly, so you could actually sent just engine such as { "horse_power" : 110, "type" : "eletric" } in order to do a partial update on cars/1 or even { "horse_power" : 110, } to just change the horse_power of the engine. I believe this is allowed by rest – mko Feb 22 '17 at 15:04
  • 1
    @mko No. The `PUT` method means *replace*. When using `PUT`, the target resource must be fully replaced with the representation sent in the request payload. For partial updates, `PATCH` must be used. – cassiomolin Feb 22 '17 at 15:29
  • does it make sense to use cars/{carsid} (with engine) for GET and cars/{carid}/engine for PUT? – mko Feb 22 '17 at 15:42
  • @mko Depending on your requirements, you could support both `GET` and `PUT` for both `/cars/{id}` and `/cars/{id}/engine`. It's up to you. – cassiomolin Feb 22 '17 at 15:46
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/136370/discussion-between-mko-and-cassio-mazzochi-molin). – mko Feb 22 '17 at 15:49
  • @mko If my answer suits you, don't forget to accept it :) – cassiomolin Mar 23 '17 at 09:38