Structuring functionality in API design

By “structuring functionality” I mean how we organize and coordinate the various endpoints of the API in order to offer customers the right features. The context here is the web API for consumption by GPS-tracking mobile phones, and I assume that most of the functionality requires a cellular or WiFi connection.

I personally prefer a more “modular” approach, where each endpoint performs basically one thing, and a collection of them fulfills all the requirements. Of course, you may need to combine some subsets or a sequence of these endpoints to achieve certain functionalities. In general, I try to minimize the overlap between the endpoints, both in terms of computation and functionality.

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

  • If the client needs to achieve functionality, then there must be one API endpoint that does just that, so the client only needs one request to perform functions with minimal caching / logic between requests.

  • For GET endpoints, if for some functions there are several levels / types of data, they prefer as much data as possible (often all the necessary data) returned by one endpoint. Ironically, they may also need a dedicated endpoint to retrieve only the "lowest level" data using the corresponding "highest level" identifier. For example, If A corresponds to a collection of B s, and each B corresponds to a collection of C s, then they will prefer a direct endpoint that extracts all the corresponding C , provided that A

  • In some extreme cases, they will request one endpoint with an ambiguous name (for example, / api / data), which returns related data from different base database tables (in other words, different resources) based on various combinations of query string parameters.

I understand that people who prefer such amenities above tend to: 1. reduce the number of API requests required to perform functions; 2. minimize data caching and data logic on the client side to reduce client complexity, which, possibly, leads to a “simple” client with simplified interaction with the server.

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

  • What are the proven and reasonable guidelines for structuring API functionality?

  • How to determine the optimal number of queries required to perform functions in a mobile application? Of course, if all other things are equal, one request is the best, but achieving such an implementation with one request usually carries a fine in other aspects.

  • Given the competition between the number of client requests and the performance and maintainability of the server-side APIs, what are the approaches to achieving a balance to ensure a reasonable design?

+7
rest api web-services api-design
source share
1 answer

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.

+13
source share

All Articles