Dherik
Dherik

Reputation: 19070

GET a resource filtering by a composite key as query parameter?

I'm thinking the best way to create an endpoint that one of the filters be a composite key.

Per example, we have a rest service to search for orders:

/orders/

We can filter the orders by start and final date:

/orders?dt-start=2017-05-11T17:12Z&dt-final=2017-05-11T17:12Z

Until here, so far so good. But I would like to filter the orders by customer. The customer is identified by his type of document and number of this document.

So, something like this could be possible:

/orders?type=ID&number=123456789

But the type and number are query parameters that only work together, it's a composite key. But using query parameter - like the last example - seems that the API user can do too:

/orders?number=123456789
/orders?type=ID

But not makes sense. Yes, I could return an error in response (bad request) if only one of these parameters were passed, but this is not natural for who are reading the API endpoint.

Another strategy is combine type and number in the same parameter, but I never see this in any API.

/orders?document=ID-12345678

It's odd to me too. I prefer to use separated parameters instead of this.

So, there are a way to use query parameter and solve this problem in a more "elegant" way?

Thanks!

Upvotes: 1

Views: 1244

Answers (2)

Kevin
Kevin

Reputation: 1450

Don't make up a composite key, instead conditionally require the two params. This ins't bad and IMO is much cleaner than creating a composite key which isn't represented by the data (or resource).

I've done this before, so to help illustrate I'll point you to it. This resource is to query for CyberFacts. The query is bound by a date range. To get data, you can do one of two things.

  1. You can say ?today=true, and get the data for today (equivalent to saying ?startDate=2017-05-13&endDate=2017-05-13)
  2. You can use the startDate and endDate query parameters, however if you use one and not the other (eg ?startDate=2017-05-13) you will receive a 400 Bad Request status response on the query and a error message in the response body.

So in this case I've done a few things to make this work

  1. Make a higher priority parameter (today overrides startDate and endDate)
  2. Document the valid behaviors
  3. Provide appropriate error responses

For you only #2 and #3 would be needed, I think. Not knowing all of your use cases, I would suggest using /orders?type=ID&number=123456789 and document that number is a require query param when type=ID, and also include the appropriate error (eg: "You queried for an Order by Type 'ID', however you did not provide a 'number' query parameter")

Upvotes: 1

Andy
Andy

Reputation: 1386

How about providing a default value for type, (such as 'ID') as a fallback if the type parameter is absent (I'd probably go for the most common/used document type depending on your situation).

While for the number parameter I would enforce it, i.e. by specifying that it is a required parameter (somewhere in the docs?). If absent, return a bad request.

Upvotes: 0

Related Questions