1

We have a REST api under design, to fetch an entity, eg persons, as follows

GET /endpoint/version/persons/

Now we can get persons who live in a particular city, as follows:

GET /endpoint/version/persons/?city=input_city

We can also get all cities where persons are as follows, this provides person id and the city, person id being unique while city may or may not repeat:

GET /endpoint/version/persons/?fields=city

The question is how should the rest api be designed if we wish to obtain the distinct list of cities?

In other words, something like

GET /endpoint/version/persons/?distinct_fields=city&sort=city

or

GET /endpoint/version/persons/?group_by=city&sort=city&fields=city

In this call we are not interested in the persons per se but the list of distinct cities.

What design would make it pleasant for the developer?

5
  • 2
    Recommended by whom? State your specific design criteria, and we'll tell you if your design meets that criteria. But don't just ask us what the best way is without something to measure "best" against. We can't answer that. Jul 8, 2016 at 0:58
  • valid point Robert. I am using vinaysahni.com/best-practices-for-a-pragmatic-restful-api as a guide to create a pragmatic rest api, not following any dogma other than this guide. Will rephrase the question.
    – alok
    Jul 8, 2016 at 2:55
  • I prefer the second version. It avoids the ambiguity that occurs if you have both fields and distinct fields, and since I assume you're mapping this onto SQL statements, GROUP BY seems more intuitive to me. DISTINCT probably applies to the entire field set anyway. Jul 8, 2016 at 3:05
  • I prefer to use 2nd one for security of sql injection do not take any sql fields in parameter or use mapper insted of direct name of fields. Jul 8, 2016 at 4:29
  • 2
    Have you considered adding a separate endpoint for cities? It can be a read only resource.
    – Chamindu
    Jul 8, 2016 at 5:39

1 Answer 1

6

The question is how should the rest api be designed if we wish to obtain the distinct list of cities?

GET /cities

Trying to do a God resource that returns all your resources depending on the query string is a bad idea and breaks REST principles.

Query strings should filter the specific collection of a resource (ie turn all people into a specific subset of people), not be used to determine which resource you are trying to get in the first place. Each resource should have a specific URL. A collection of people having its own URL is ok, but having both cities and people resources at the same URL is confusing and adds complexity to the client implementation.

You should also not build your URL scheme around a single possible use case of the client. Let the client worry about why it wants a resource. By expecting the client to get Cities via the People you are forcing client designers to understand that on your system that is how you get cities.

One final point unrelated to the question but still important. Using query strings to filter the data returned (ie ?field=city) is a design smell. The content type negotiation should determine how the resource looks to the client, if the client wants the representation in a specific format it should tell the server this via the header, not the URL. The reason for this is again not to add business level complexity to the URL scheme.

4
  • What if cities does not exist as resource but it's just a field of person? In this example it's clear that cities can be a separate resource, but there are cases where it is just a field and it does not exist as a separate resource. What if we want to allow fetching different distinct fields?
    – Danielo515
    Mar 19, 2018 at 19:34
  • If there is a use case that a client of your API wants to fetch a city on its own then it is a distinct resource. Anything can be a separate resource, resources do not need to map directly to your database model. Resources exposed by the API and your database model are two distinct things. You might have a single database table and tons resources exposed by the API. You might have resources that have nothing to do with the database table. Mar 21, 2018 at 8:46
  • Hello @cormacmulhall. You're absolutely right, I think your proposal is the way to go. However, what happens when you have a field has the same name under several resources but it is not the same thing ? How do you indicate the correct source of that field ?
    – Danielo515
    Mar 21, 2018 at 11:52
  • Not quite following, can you give an example? Mar 22, 2018 at 14:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.