4

I have question about how to organize API route structure. Have read many books about building RESTful APIs and couldn't find answer for that. Every book tells about simple CRUD actions, and nested resources in one level. Like /users and /users/1/posts. No problem with that.

EXAMPLE:

But let's look at more difficult real life example:

GET /cars // List of cars
GET /cars/{car_id} // Get single car
POST /cars // Add new car
PUT /cars/{car_id} // Update existing car
DELETE /cars/{car_id} // Delete car by specified ID

Structure for database table of cars would be

Table "cars"
    - id
    - uuid
    - make
    - model
    - year
    - created_at
    - updated_at
    - deleted_at

No problems so far, but then I need to add nested resource. All repairs that were done with specified car.

GET /cars/{car_id}/repairs // List of repairs that were done with car
GET /cars/{car_id}/repairs/{repair_id} // Get single repair
POST /cars/{car_id}/repairs // Add new repair for specified car
PUT /cars/{car_id}/repairs/{repair_id} // Update existing repair for specified car
DELETE /cars/{car_id}/repairs/{repair_id} // Delete repair by specified ID

Structure for database table would be

Table "car_repairs"
    - id
    - uuid
    - car_id ( foreign key to cars )
    - title
    - description
    - repair_started_at
    - repair_ended_at
    - created_at
    - updated_at
    - deleted_at

So far no problem. Like in all books. a /users route and nested route /users/1/posts. But then here starts problem, when I need to add another level of nesting.

I need CRUD routes for all defects that were found when car was on repair

GET /cars/{car_id}/repairs/{repair_id}/defects // List of all defects that were found for specified repair for speicified car
GET /cars/{car_id}/repairs/{repair_id}/defects/{defect_id} // Get single defect
POST /cars/{car_id}/repairs/{repair_id}/defects // Add new defect
PUT /cars/{car_id}/repairs/{repair_id}/defects/{defect_id} // Update existing defect
DELETE /cars/{car_id}/repairs/{repair_id}/defects/{defect_id} // Delete existing defect

Table structure would be:

Table "car_repair_defects"
    - id
    - uud
    - car_id
    - repair_id
    - name
    - description
    - created_at
    - updated_at
    - deleted_at

QUESTSIONS:

What to do here, is level of .../defects normal practice or not ?

Consider situation if I need to add another, 4th level of nesting, at example, all parts that were used for found defect

What best practice when nesting resources in RESTful API's

One can say that this can be done without nesting. Example /cars /repairs /defects /parts But then, what about RESTful examples with nested resources. Then what is maximal level of nesting resource 0, 1, 2, 3 ?

Also if it will be done without nesting, at example, you need to create dictionary route /defects that just lists all possible car defects. So there would be name collision.

Also, if there is no nesting, how would you filter items, that you would filter with nesting ?

defects?car_id=1&repair_id=2&defect_id=3

Like this ? This looks ugly.

Please can someone point to a book or article, or give answer about maximal level of nesting and questions listed before. Thank you.

user991
  • 1,339
  • 2
  • 24
  • 45
  • If my question gets down-voted, please comment why? – user991 Dec 27 '17 at 16:49
  • Your questions is exactly what I am wondering right now. Did you find some best practices or solution in the meantime? – mlst Mar 22 '21 at 11:42
  • @mlst Check this article https://www.moesif.com/blog/technical/api-design/REST-API-Design-Best-Practices-for-Sub-and-Nested-Resources/ – user991 Mar 22 '21 at 18:09
  • @mlst And also other StackOverflow question about same topic https://stackoverflow.com/questions/20951419/what-are-best-practices-for-rest-nested-resources – user991 Mar 22 '21 at 18:11

1 Answers1

2

Here's the key point: REST doesn't care what spelling you use for your identifiers.

Which is to say, REST considers each of these URI to be equally good.

/cars/{car_id}/repairs/{repair_id}/defects
/08617423-cc74-4967-9a67-49e4171f01b7

As far as the client is concerned, the identifier is opaque; encoding information into the URI is done at the discretion of the server for its own exclusive use.

Beyond that, identifier spelling conventions are effectively code style conventions; use spellings that are consistent with the local style.

From the client's perspective, the identifier does not describe the semantics of the resource; that's the job of the hypermedia representation.

VoiceOfUnreason
  • 52,766
  • 5
  • 49
  • 91