I'm working on rest endpoint which must returns "all availables cities" grouping by "state". I returns the following object:
@Builder
@Data
class CitiesByState
{
Map<String, List<Cities>> citiesByStateName;
}
Everything work without any issue but. I'm block with naming convention. What is the best naming convention for this kind of endpoint ?
http://url/api/cites?group-by=state
http://url/api/state/cities
?
Since State name
is used as key
I would prefer
http://url/api/states/{statename}/cities
, which also enables cacheable
constraint of REST.
A lot on this has been described here
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 ?
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.
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:
/cities
. Maybe separately a resource for groups available, that may appear as attribute inside each city: /states
.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)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With