Search code examples
urisymfony4restdbal

REST URI - GET Resource batch using array of ID's


The title is probably poorly worded, but I'm trying my hand at creating a REST api with symfony. I've studied a few public api's to get a feel for it, and a common principle seems to be dealing with a single resource path at a time. However, the data I'm working with has a lot of levels (7-8), and each level is only guaranteed to be unique under its parent (the whole path makes a composite key).

In this structure, I'd like to get all children resources from all or several parents. I know about filtering data using the queryParam at the end of a URI, but it seems like specifying the parent id(s) as an array is better.

As an example, let's say I have companies in my database, which own routers, which delegate traffic for some number of devices. The REST URI to get all devices for a router might look like this:

/devices/company/:c_id/routers/:r_id/getdevices

but then the user has to crawl through all :r_id's to get all the devices for a company. Some suggestions I've seen all involve moving the :r_id out of the path and using it in the the query string:

/devices/company/:c_id/getdevices?router_id[]=1&router_id[]=2

I get it, but I wouldn't want to use it at that point.

Instead, what seems functionally better, yet philosophically questionable, is doing this:

/devices/company/:c_id/routers/:[r_ids]/getdevices

Where [r_ids] is a stringified array of ids that can be decoded into an array of integers/strings server-side. This also frees up the query-parameter string to focus on filtering devices by attributes (age, price, total traffic, status).

However, I am new to all of this and having trouble finding what is "standard". Is this a reasonable solution?

I'll add I've tested the array string out in Symfony and it works great. But I can't tell if it can become a vehicle for malicious queries since I intend on using Doctrine's DBAL - I'll take tips on that too (although it seems like a problem regardless for string id's)


Solution

  • However, I am new to all of this and having trouble finding what is "standard". Is this a reasonable solution?

    TL;DR: yes, it's fine.

    You would probably see an identifier like that described using a level 4 URI Template, with your list of identifiers encoded via a path segment expansion.

    Your example template might look something like:

    /devices/company{/c_id}/routers{/r_ids}/devices
    

    And you would need to communicate to the template consumer that c_id is a company id, and r_ids is a list of router identifiers, or whatever.

    You've seen simplified versions of this on the web: URI templates are generalizations of web forms that read information from input controls and encode the inputs into the query string.