Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Functionalities structuring in API design

By 'functionalities structuring', I mean how we organize and coordinate different API endpoints to offer desired functionalities to clients. The context here is web APIs for consumption by mobile phones with GPS tracking, and I assume either cellular or WiFi connectivity is required for most functionalities.

I personally prefer a more 'modular' approach where each endpoint does mostly one thing and a collection of them fulfill all the requirements. Of course, you may need to combine some subset or sequence of these endpoints to achieve certain functionalities. Overall, I try to minimize the overlapping between endpoints in terms of both computation and functionalities.

On the other hand, I know some other people prefer client-side convenience (or simplicity) over modularity in the following ways:

  1. If the client needs to achieve a functionality, then there should exist a single API endpoint which does exactly that, such that the client needs only a single request to fulfill the functionality with minimal caching/logic in between requests.

  2. For GET endpoints, if there are multiple levels/kinds of data involved for some functionalities, they prefer as much data as possible (often all necessary data) returned by a single endpoint. Ironically, they may also want a dedicated endpoint for retrieving only the "lowest level" data using a corresponding "highest level" ID. For example, If A corresponds to a collection of Bs, and each B corresponds to a collection of Cs, then they will prefer a direct endpoint that retrieves all the relevant Cs given an A.

  3. In some extreme cases, they will ask for a single endpoint with ambiguous naming (e.g. /api/data) that returns related data from different underlying DB tables (in other words, different resources) based on different combinations of query string parameters.

I understand that people preferring such conveniences above aim to: 1. reduce the number of API requests necessary to fulfill functionalities; 2. minimize data caching and data logic on the client side to reduce client complexity, which arguably leads to a 'simple' client with simplified interaction with the server.

However, I also wonder if the cost of doing so is unjustifiable in other aspects in the long run, especially in terms of the performance and the maintenance of the server-side API. Hence my questions:

  1. What are the tried-and-true guidelines for structuring API functionalities?

  2. How do we determine an optimal number of requests necessary for fulfilling a functionality in a mobile app? Of course, if all other things equal, a single request is the best, but achieving such a single-request implementation usually carries penalty in other aspects.

  3. Given the contention between the number of client requests and the performance and maintainability of server-side API, what are the approaches for striking a balance in order to deliver a sensible design?

like image 777
MLister Avatar asked Aug 26 '15 05:08

MLister


People also ask

What is API design?

API design refers to the process of developing application programming interfaces (APIs) that expose data and application functionality for use by developers and users. APIs are important to modern organizations, adding new capabilities to everything from their operations and products to their partnership strategies.

What is an API function?

In this article, we define API functions, list some types of APIs, explain their components and provide three examples of them in use. What are API functions? An application programming interface (API) functions with the goal of allowing different systems, applications and devices to share information with each other.

What is the best approach for REST API design?

There is no single approach in the REST API design rulebook that will work for all organizations. That is why it is essential for API developers to tailor the design process according to use cases and make it flexible enough to be accessible to other interested parties. Consumer needs are the guiding light for building and designing great API.

How can organizations take advantage of the API?

An organization that has unique data could take advantage of this resource by allowing access to the data via API. Unique content, data, and services can make access to the API extremely valuable.


1 Answers

What you are asking about breaks into at least three main areas of API design:

  1. Ontology Design (organization)
  2. Request/Response Design (complexity/performance)
  3. Maintenance Considerations

Based on my experience (which is largely from working with very large organizations both on the API producing and consuming side and talking with hundreds of developers on the topic), let's look at each area, addressing the specific points you bring up...

Ontology Design

There are a couple of things to take in to consideration in your design that are perhaps implied when you say:

Overall, I try to minimize the overlapping between endpoints in terms of both computation and functionalities.

This approach makes the APIs easily discoverable. When you are in a situation where you are publishing APIs for consumption by other developers who you may or may not know (and may or may not have enough resources to truly support), this kind of modularity - making them easy to find and learn about - creates a different kind of "convenience" leading to easier adoption and reuse of your APIs.

I know some other people much prefer convenience over modularity: 1. if the client needs a functionality, then there should exist a single endpoint in the API which does exactly 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 data requested, ex:

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 that example we are querying Google Analytics Account 12134 for pageviews by browser where broswer is Firefox for the given date range.

Given the number of metrics, dimensions, filters, and segments their API exposes, they have a tool called the Dimensions & Metrics Explorer to help developers understand how to use the APIs.

One approach makes the APIs discoverable and more understandable from the outset. The other requires more supporting work to explain the intricacies of consuming the API. One thing that isn't immediately obvious with the Google API above is that certain segments and metrics are incompatible, so if you are making calls passing one key/value pair, you may not longer be able to pass certain other pairs.

Request/Response Design

The context here is APIs for mobile applications.

That is still very broad, and better defining (if possible) how you intend for your "mobile applications" to be used can help you design your APIs.

  1. Do you intend for them to be used totally offline? If so, heavy/complete data caching may be desirable.

  2. Do you intend for them to be used in low bandwidth and/or high latency/error-rate connectivity scenarios? If so, heavy/complete data caching may be desirable, but so might small/discrete data requests.

for GET endpoints, they often prefer as much data as possible returned by a single endpoint, especially when there are multiple levels/layers of data involved

This is safe if you know you'll only ever be in good mobile connectivity scenarios, or you can cache the data heavily when you are (and thus access it offline or when things are spotty).

I understand that people preferring convenience aim to reduce the number of API calls necessary to achieve functionalities...

One way to find a happy middle ground is to implement paging in your data-intensive calls. For example, a querystring can be passed in a GET specifying 'pagesize'. Thus 10,000 records could be returned 100 at a time over 100 successive calls, or 1,000 at a time over 10 calls.

With this approach, you can design and publish your API without necessarily knowing what your consuming developer will need. Even though the paging example above uses the Google API referenced earlier, it can still be used in a more semantically designed API. For example, say you have GET /customer/phonecalls you could still design it to accept a pagesize value and make successive calls to get all the phonecalls associated with customer.

Maintenance

I also wonder if the cost of doing so [reduce the number of API calls necessary to achieve functionalities and to minimize data caching] is not justifiable in the long run, especially for the performance and the maintenance of an API.

The key guiding principle here is separation of concerns if your collection of APIs is going to grow to any significant level of complexity and scale.

What happens when you have everything bundled together into one big service and a small part of it changes? You are now creating not only a maintenance headache on your side, but also for your API consumer.

Did that "breaking change" really affect the part of the API they were using? It will take time and energy for them to figure that out. Designing API functionality into discrete, semantic services will let you create a roadmap and version them in a more understandable way.

For further reading, I'd suggest checking out Martin Fowler's writings on Microservices Architecture:

In short, the microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms

Although there is a lot of debate about how to design and build for "microservices" in practice, reading up on that should help further shape your thinking on the API design decisions you're facing and prepare you to engage in "current" discussions around the topic.

like image 188
busse Avatar answered Sep 28 '22 09:09

busse