3
votes

Let's take a generic example of resources you might model with a restful API built in PHP.

  • A garage has multiple cars and multiple mechanics.
  • A car has only one garage.
  • A mechanic has multiple cars and multiple garages (he's a workaholic ok!).

So logic says that our endpoints should be

/v1/garages  
/v1/garages/1234
/v1/mechanics
/v1/mechanics/1234
/v1/cars
/v1/cars/1234

If we wanted to get all cars of garage 1234 we would use GET /v1/garages/1234/cars

If we wanted all cars for mechanic 12 that are in garage 34 we would use GET /v1/mechanics/12/garage/34/cars

But what about if we wanted all cars from garages 56 AND 78?
I have a few ideas in mind but the best I can think of is GET /v1/cars?garage=[id=[56,78]]

Which would allow us to grab all green cars with two or four doors from any garages that have yellow paint and carbon bonnets via GET /v1/cars?garage=[paint=yellow,bonnet=[material=carbon]]&color=green&doors=[2,4]

Does this seem like a reasonable idea or am I going to run into issues with this getting to complex with the nesting, should this be easy enough to parse with PHP?

Another idea I had was Json as far as I am aware all json is valid in a url so

GET /v1/cars?{"color":"green","doors":[2,4],"garage":{"paint":"yellow","bonnet":{"material":"carbon"}}}

Which makes it super easy for developers to use then as almost all programming languages now have json support, and on the API end we can just use json_decode($_SERVER[''QUERY_STRING]) so are there any issues with using Json?

Third Idea "create a search"

By this I mean we use

POST /cars/search with the above Json as post data that request will simply return the ID of the search to which the results could then be fetched via GET /cars/search/{id} this would alleviate the complexity on my side and avoid the 8kb limit for requests (this is an API, not meant to be used by browser address bars). but I am concerned that if I do this then it defeats the purpose of the top level GET /v1/cars endpoint?

1
@DavidBrabant, While the question is similar, it doesn't really answer the question in full; I had actually read that question (and a lot of others on here) before posting this question. Primarily the answers on that question deal only with single entity searches instead of filtering across multiple entities which is the main focus of this question.Hailwood

1 Answers

0
votes

Thanks to the helpful guys over at the #laravel irc channel who I had rather an extended conversation with we have an answer that seems to work.

We chose this answer based on a few thing:

  • Ease of human readability
  • Power of queries
  • Flatness (Ease of parsing)
  • Ease of filtering

The basic request would be

GET /v1/cars?color=green
            &doors=2,4
            &garage[paint]=yellow
            &garage[bonnet][material]=carbon

Which when combined with the following code

$query = array();
parse_str($_SERVER['QUERY_STRING'], $query);

Spits out an array like below which can be easily iterated over in the API to do the filtering :)

Array
(
  [color] => green
  [doors] => 2,4
  [garage] => Array
    (
      [paint] => yellow
      [bonnet] => Array
        (
          [material] => carbon
        )
    )
)