2

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

?

ltone
  • 117
  • 9

2 Answers2

2

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

Raj
  • 131
  • 6
  • I like your solution, however the client should call 1 time in ordre to retrieve all state (50) and we should call API states/{statename}/cites (50 times). do we affected by a performance problem ? – ltone Sep 17 '20 at 16:08
  • for that case just using cities api URL, without state param suits better... `http://url/api/cities` – Raj Sep 17 '20 at 21:51
0

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:

  1. 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.
  2. 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.

Community
  • 1
  • 1
hc_dev
  • 8,389
  • 1
  • 26
  • 38