What do you ask for a break in at least three main areas of the API design:
- Ontological design (organization)
- Request / Response Design (Complexity / Performance)
- Service Issues
Based on my experience (which is largely related to working with very large organizations both on the side producing and consuming the API, and in negotiations with hundreds of developers on this topic), let's look at each area, considering the specific points that you raise ...
Ontology design
There are a few things you need to consider in your design, which may be implied when you say:
In general, I try to minimize the overlap between endpoints in terms of both computation and functionality.
This approach allows the API to be easily discovered . When you are in a situation where you publish an API for consumption by other developers that you may or may not know (and may or may not have sufficient resources for real support), such modularity - simplifying the search and learning - creates another "convenience", which simplifies the implementation and reuse of your APIs.
I know that some other people prefer convenience over modularity: 1. if the client needs functionality, then there must be one endpoint in the API that does just that ...
The best public example that comes to mind for this approach is perhaps the Google Analytics Core Reporting API . They implement a series of querystring parameters to build a call that returns the requested data, for example:
https://www.googleapis.com/analytics/v3/data/ga ?ids=ga:12134 &dimensions=ga:browser &metrics=ga:pageviews &filters=ga:browser%3D~%5EFirefox &start-date=2007-01-01 &end-date=2007-12-31
In this example, we request a Google Analytics account 12134 for pageviews by a browser where broswer is Firefox for a given date range.
Given the number of metrics, sizes, filters, and segments that their API provides, they have a tool called Dimensions and Metrics Explorer to help developers understand how to use the API.
One approach makes the API accessible and understandable from the start. Another requires additional support to explain the intricacies of using the API. One thing that is not immediately apparent in the above Google APIs is that certain segments and metrics are incompatible, so if you make calls that go through the same key / value pair, you can no longer transfer some other pairs.
Request / Response Design
The context here is the API for mobile applications.
This is still very broad, and it’s best to determine (if possible) how you intend to use your “mobile applications” that can be used to develop your APIs.
Are you going to use them offline? If so, heavy / full data caching may be required.
Do you intend to use them in scenarios with low bandwidth and / or high latency / error? If so, heavy / full data caching may be required, but small / discrete data requests may be required.
for GET endpoints, they often prefer as much data as possible returned by a single endpoint, especially when multiple data layers / layers are involved.
This is safe if you know that you will only ever be in good scenarios for mobile connections, or you can cache the data strongly when you are (and thus access it offline or when everything is spotty).
I understand that people who prefer convenience tend to reduce the number of API calls needed to achieve functionality ...
One way to find a happy middle ground is to implement paging in your intensive calls. For example, a request may be submitted to GET with the indication "pagesize". Thus, 100,000 records can be returned 100 at a time over 100 consecutive calls or 1000 times in 10 calls.
With this approach, you can design and publish your API without knowing what your developer developer will need. Although the paging example above uses the previously mentioned Google API, it can still be used in a more semantically developed API. For example, suppose you have GET /customer/phonecalls , you can still create it to accept pagesize and make consecutive calls to get all the phonecalls associated with customer .
Service
I also wonder if it would be worth it to [reduce the number of API calls needed to achieve functionality and minimize data caching], in the long term, it is impractical, especially for the performance and maintenance of the API.
The basic guiding principle here is sharing problems if your collection of APIs grows to any significant level of complexity and scale.
What happens when you have everything together in one big service, and a small part of it changes? Now you are creating not only a service headache on your side, but also for your consumer API.
Did this “breaking change" really affect part of the API used? It will take them time and energy to figure this out. Designing API functions in discrete, semantic services allows you to create a roadmap and change them in a more understandable way.
For further reading, I suggest checking out Martin Fowler's work on Microservices Architecture :
In short, the architectural style of a microservice is an approach to developing a single application in the form of a set of small services, each working in its own process and communicating with light mechanisms
Despite the fact that in practice there is a lot of discussion about how to create and create for "microservices", reading on this should help to further shape your thinking about the API design decisions that you come across, and prepare you to participate in "ongoing" discussion of the topic.