14

For example I have entities: Client, Report. Client may have many Reports and I think the endpoint for a single Report management should be nested like this:

/clients/{client_id}/reports/{report_id}

As for all the reports of one client the enpoint is expected:

/clients/{client_id}/reports

But how should look an endpoint for getting all the Reports of all the Clients to keep API consistent and well designed.

My approaches:

  1. (I saw it in some google api) use "-" instead of it and parse it as "all":

/clients/-/reports

This keeps endpoint format the same, but looks a bit unusal, can't find any rfc that suggest this way.

  1. Make a separate endpoint just for all the reports:

/reports

But to get Client's Reports it's still:

/clients/{client_id}/reports

  1. Refactor endpoints to make "client" not a parent, but just a filter parameter:

/reports?client={client_id} - reports of one client

/reports - reports of all the client

In case of adding a new endpoint for posting a report for a specific client, It may look ugly, because it will be a POST-request with a parameter in URL.

Is there any other suggestions of ideas?

1
  • 2
    You might be interested question
    – Laiv
    Aug 24, 2017 at 15:39

2 Answers 2

5

But how should look an endpoint for getting all the Reports of all the Clients to keep API consistent and well designed.

Before anything else, remember that there are no golden rules for modelling RESTful APIs. All we have are best practices and conventions. That being said, the likely answer is -as usual- to choose the one that best meets your requirements and in this case, the one that best expresses your model.

So check the three options from the expressiveness.

#1 The "-" notation

This is a good idea. It allows us to express the condition all reports pertaining to clients. It's narrowing down the "query" to a specific set of reports (those located within the clients boundary).

It keeps the notion of hierarchy (belonging) all the time, so if reports can be found in different locations, this notation makes a big deal. For example:

  • All reports pertaining to clients /clients/-/reports
  • All reports pertaining to departments /departments/-/reports
  • All reports pertaining to employees /employees/-/reports

However, to retrieve all reports available, the hierarchy doesn't provide any valuable advantage over the next option.

#2 Different URIs

If we don't need to communicate boundaries/contexts/hierarchy when retrieving all reports available, the following approach seems more reasonable.

The new URI (/reports) also leaves the possibility for reports management. Meanwhile, supporting GET and some filters should be enough.

Note that you still could do this /reports?client={client_id}. Having different URI for the same resource is fine. I would call this robustness.

#3 Reverting the hierarchy

I get the feeling that this approach doesn't meet your expectations. Plus, I think, It will bring you eventually to the starting point.

Conclusions

#1 and #2 are not mutually exclusive. You can implement both. Given the actual situation and according to the OP's premises, option #2 seems the way to go.


1: it's equivalent to /clients/-/reports I guess

0

Google's API design patterns suggest using '-' in this scenario.

GET /clients/-/reports

Source:

https://cloud.google.com/apis/design/design_patterns#list_sub-collections

8
  • 2
    Far be it for me to disagree with the almighty Google, but I think I'd prefer something like /client/{client_id}/report/{report_id} and /clients/report/{report_id} Aug 24, 2017 at 15:40
  • 2
    @RobertHarvey why not just /reports?
    – Laiv
    Aug 24, 2017 at 15:42
  • @Laiv: That would imply all reports. Refresh your page; I made a ninja edit. Aug 24, 2017 at 15:43
  • @RobertHarvey I mean, why not 2 different endpoints /clients...and /reports.
    – Laiv
    Aug 24, 2017 at 15:46
  • 1
    @Laiv: OK, but that just raises the question "Which parameters should I put in the request body?" Aug 24, 2017 at 15:55

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.