Assume you have a collection resource /cities
which lists all cities.
Assuming further a city has many attributes (like state, population, etc.).
Wouldn't you as a client (the REST consumer, like a JavaScript driven web-app) like to have the choice for which attribute to group ?
Coupling the resource to a representation identified by URI
Your approach restricts that flexibility by predefining a variant for this cities resource's representation.
Like /cities?by-state
. But that would dictate fixed-coupling, because grouping now depends on the client and the server's implementation too. Every time you change grouping on the client side for a use-case, you would have to adjust the server side too.
Delegate grouping to the client
Fielding applied separation of concerns in 5.1.2 Client-Server:
Separation of concerns is the principle behind the client-server constraints. By separating the user interface concerns from the data storage concerns, we improve the portability of the user interface across multiple platforms and improve scalability by simplifying the server components.
Benefit: You would stay much more flexible by performing the grouping on client-side.
Applying that separation of concerns decouples the client from the server:
- The server-side interface provides access to stored data. Here: the raw list of cities by
/cities
. Maybe separately a resource for groups available, that may appear as attribute inside each city: /states
.
- The client-side framework (be it a Python script or JavaScript web-app) can group the data, transform a simple list of cities into a grouped list, tree, map, or whatever.
How the client could group:
Following JavaScript pseudo-code, inspired by javascript - Most efficient method to groupby on an array of objects - Stack Overflow:
const groupBy = (x,f)=>x.reduce((a,b)=>((a[f(b)]||=[]).push(b),a),{});
var cities = restApi.get("/cities");
var citiesGroupedByState = groupBy(cities, c => c.state)
Which Conventions?
Neither REST (in dissertation by Roy Fielding), nor the RFC 3986 (along Tim Berners-Lee) foresee naming conventions:
The path component contains data, usually organized in hierarchical form, that, along with data in the non-hierarchical query component (Section 3.4), serves to identify a resource [..]
See them implemented for example in API Standards of the Australian Government, section Naming Conventions:
URLs MUST follow the standard naming convention as described below:
/namespace/project-name/v1/collection?attributes=first_name,last_name
\___________________________________/\______________________________/
| |
path query
And you may ask, how can a client request a specific representation (response type like a grouped Map
) when querying an URL?
Answered in Untangled - musings of Roy T. Fielding, REST APIs must be hypertext-driven:
A REST API should never have “typed” resources that are significant to the client. Specification authors may use resource types for describing server implementation behind the interface, but those types must be irrelevant and invisible to the client. The only types that are significant to a client are the current representation’s media type and standardized relation names.