Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to ensure the Stability of API Design

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Servers >

Share

Shulou(Shulou.com)05/31 Report--

How to ensure the stability of API design, in view of this problem, this article introduces the corresponding analysis and solution in detail, hoping to help more partners who want to solve this problem to find a more simple and feasible method.

There is a famous saying in the computer industry that any problem in computer science can be solved by adding an indirect middle layer.

No one can fully master the breadth or depth of the current computer field. However, through the combined use of various intermediate layers, we do not need to know its internal details, but also like building blocks, we can develop a variety of interesting services and applications.

The reason why the various middle layers can work together is precisely because everyone interacts and communicates through the defined API. While each module provides abstract API, it also needs to use the API of other modules as the basis for its own operation.

Today we will talk about some practices in designing the API process to ensure stability.

Ubiquitous API

API (Application Programming Interface) is also known as the application programming interface.

Interface, in essence, can be understood as a contract, a kind of agreement.

The concept of computer interface originates from hardware. In the early days, all kinds of components developed by various companies are neither universal nor standard, so it is very difficult to use each other, so we agreed on the functions and specifications, resulting in an interface, which later spread to the software.

After the interface spreads to the software, it is divided into ABI (Application Binary Interface) and API (Application Programming Interface).

The former mainly prescribes the rules of binary operation and access, while the latter focuses on the interaction of logical modules. The following content of this article only discusses API that developers often come into contact with.

Many people's impression of API is just a Class or header file containing some functions. But API is everywhere in our lives, but we sometimes don't notice it.

For example, when we are making a phone call, the whole system of communication between the mobile phone and the base station is very complex.

Fortunately, we do not need to know the internal details, we only need to send the 11-digit phone number to the interface of the "telephone system", and the hidden country code (such as + 86) can be understood as the default parameter of the interface.

There are a lot of details hidden behind this highly abstract API. With the help of the above middle-tier theory, we can systematically discuss what needs to be considered in designing an API.

How is the API exposed by the module to the upper layer used?

API can be divided into two categories in terms of the coupling methods used: one is called through the protocol, such as calling the HTTP interface, and the other is called directly by the language through the declaration.

For example, when designing HTTP Restful API, you don't need to care about the user's operating system, programming language, memory thread management, etc., so it will be simpler than the latter.

From the scale and controllable range of users, API can be divided into LSUD (Larget Set of Unkown Developers) and SSKD (Small Set of Kown Developers).

The former is generally an open cloud service on the public network, which can be used by any developer. It is impossible to predict in advance how it will be used, and the version is uncontrollable. The communication cloud provided by Rongyun is this kind of API.

The latter has a limited user base and is generally within the same company or team. For example, the modular API provided internally is quite popular some time ago, the scope and mode of use can be controlled, and there is generally no need to struggle with backward compatibility when updating.

The first audience of API is people, then machines, so "understandability" needs to be given priority in design.

Good API documentation, simple Demo, and key log can enhance the experience of API users.

How does the module to which API belongs depend on the lower layer?

The modules to which API belongs run in a certain address space. The environment variables, load libraries, memory and threading models, system and language features all need to be considered.

How does the internal implementation of the module to which API belongs affect other layers?

In general, a well-designed API does not need to understand its internal implementation when it is used. However, if you can understand its internal architecture and assist the key log, it will help to improve the efficiency of using API.

And the internal implementation of the module sometimes affects the style of API design.

If an interface is strongly dependent on IO, you may need to use an asynchronous approach. A large number of asynchronous ways give rise to frameworks such as RxJava.

Backward compatibility

Because API is so important and involves such a wide range of areas, it can be said that the majority of developers have high requirements for backward compatibility of API.

After all, no one wants to update interfaces and code frequently in the development process, and it scares me to think about the tragedy of "swift from getting started to being proficient to getting started again."

Not only do we ask why many companies or projects are not backward compatible, just because there is not enough investment or attention, or is it impossible to be 100% backward compatible in practice?

Assume that the design is ideal and proven, just like a perfect circle.

Design is to be implemented in the coding, and the coding process is always inevitable to introduce some bug, and with a version of bug implementation, in fact, just like an Amoeba amoeba, the shape is not fixed. With the continuous evolution of the version, it is inevitable that there will be some differences.

The first version implements:

The second version implements:

So 100% backward compatibility itself is impossible.

Therefore, when people usually talk about the stability of API, the default is to include a certain degree of change.

However, because the scope of API is too wide, it is very expensive to guarantee backward compatibility.

For example, Linux wants to iterate quickly and does not guarantee the stability of API at all. To solve this problem, Linux also specially wrote stable-api-nonsense documents.

If you are interested, you can click to read: stable-api-nonsense.rst

Progressive improvement

Therefore, there are many challenges to ensure the stability of API, such as:

* the business form is not stable and is still developing at a high speed.

* heavy burden on business and API history

* the features of multiple platforms and languages are inconsistent

* the user base and usage are not clear

Let's review the normal development process to see if we can improve the stability of API through some indicators and tools, mainly involving: requirements, design, coding, Review, testing, release, feedback and other steps.

Demand for

For ordinary product development, when starting up, the needs of users are relatively clear, but for LSUD's cloud services, it is impossible to predict in advance what the user base is and how users use API in his products.

This is easy to cause, without clear user requirements, it is difficult for API to design and iterate. Without design, there will be no users, and the requirements are out of the question. This is a problem of chickens laying eggs and eggs.

It is recommended that before the release of API, several complete Demo can be designed internally for typical usage scenarios to verify whether the design and use of API is reasonable.

It should be noted that Demo needs to have a complete application scenario to the extent that it can be put on the shelf. If it can be used internally, Eating your own dog food is the best. Too simple Demo can not expose the use of API in advance.

Demo developers had better distinguish from API designers to avoid thinking solidification. For more content, you can refer to some practices of Rust language development in the bootstrap process.

Cymbal design

When designing API, there are a lot of points to pay attention to that are different from ordinary development.

General development, rapid implementation of the function is always put in the first place. For example, people will use some agile development methods, give priority to the implementation of functions and then quickly iterate, and so on.

But when API is designed, the interface cannot be changed frequently, so the first thing to consider is "less", less is more.

L each API does less.

An interface only does one thing, and it is enough to do it well.

You need to avoid performing complex combinational logic on an API to please a scenario, providing an interface similar to syntactic sugar. Otherwise, when the business of the scenario itself is evolving, it is difficult to ensure that the behavior of API remains the same.

If you need to support multiple services, you can consider tiering the API. For example, the API of the cloud-melting client will be divided into the following layers.

For example, Rongyun considers versatility and abstracts RTCLib based on the subscription distribution model. The client can handle any stream of media, which is very flexible, but for users, the development cost may be higher, and there is a lot of work to think about and do.

Considering the large number of users, what is actually needed is audio and video calling service. Based on RTCLib, Rongyun installs CallLib without UI and CallKit with integrated UI.

If a user's needs are similar to Wechat's audio / video calls, he / she can integrate CallKit with UI interface, and the development efficiency will be very high.

If users have a lot of demand for the interaction of audio and video calls UI, they can develop based on CallLib, and UI can be customized.

L expose less information

Mature API designers will hide the internal implementation details as much as possible.

For example, fields should not be directly exposed but provided through Getter/Setter, unnecessary classes, methods, and fields should be hidden, which have become the basic requirements of each language, so I will not elaborate on them here.

But the point that is easy to be overlooked needs to remind everyone that the information of the technology stack should be hidden as much as possible.

For example: API http://api.example.com/cgi-bin/get_user.php?user=100, obviously mixed with a lot of useless information, and later technology switching upgrades to maintain API stability is very troublesome.

L behavior diffuses less

In API, which is called directly by the language, it is necessary to avoid behavior diffusion caused by inheritance of the underlying interface.

Abstract classes and inheritance are powerful object-oriented weapons in the general coding process. But for API, it is more recommended to use it in combination.

For example, if a class that manages the life cycle is inherited, some behaviors of the subclasses may be modified to cause errors. At this point, it is recommended to use the method of Interface + factory to provide an example.

Since interface did not have a default implementation before Java 8, final class can be used to avoid frequent interface modifications to increase functionality.

Objetive-C can use _ _ attribute__ ((objc_subclassing_restricted)) and _ _ attribute__ ((objc_requires_super)) to control subclass inheritance behavior.

L there is less switching of painting style.

API naming should unify the business naming of multiple platforms and the style of each platform.

The interface of HTTP is simpler, you only need to choose a style, Restful or GraphQL or define it yourself.

For API naming of language calls, it is recommended that you first follow the style of the platform, then refer to the language standards, and finally consider the style of the team.

For example, API development on the iOS platform needs to first refer to the naming style of iOS, and tenses such as did and will are very distinctive.

There are many details in naming, such as vocabulary, tense, singular and plural, preposition, lowercase, synchronous and asynchronous style, etc., which need to be accumulated over a long time.

L understand that the cost should be less.

Generally speaking, there are comments for every interface in API, but it is worth noting that most developers do not read the comments.

Most developers know about the interface only from the completion and reminder of IDE. One interface looks like it can be used directly, but if you can't try another one, it's actually an empirical programming method.

This means that interface naming needs to be more understandable. There is a way to verify that by erasing all comments on the interface, the user can understand the meaning of each interface very directly. If it is difficult, it needs to be improved.

There is another aspect of API design that is not quite consistent with ordinary development. Ordinary developers can design the architecture, the development of each module may be the same person, and the interface does not need to be determined at design time.

However, in the design stage of API, it is necessary to carry out Review and determine the design of the interface directly, so as to ensure that many sides follow the rules completely all the time when developing.

Blind coding

In the coding process of API, there are several points to pay attention to.

In API, the version number is predefined.

This is mainly aimed at HTTP API, such as http://api.example.com/v1/users/12345?fields=name,age. If there is only one version at present, you can not add it for the time being and make a distinction in the second edition.

Pay attention to API version checking.

When layering provides multiple API, each layer of API needs to check the version number at startup to avoid mismatch.

For example, in the following Java code, you may find it very strange to judge that the version number is equal, and it should always be true.

However, the abstract class and the implementation class appear in different hierarchical modules, and the implementation class is compiled first, and then compiled after the abstract class version is updated, there will be inconsistencies. There are many languages or platforms that provide a similar way to determine versions.

Provides normative log output.

Log, commonly developed, is mainly used to locate problems on their own. However, when API is coding, it is best to add some log pertinently, which is helpful for API users to understand and simply troubleshoot the problem.

However, for performance reasons, the level of log needs to be defined and can be adjusted.

Pay attention to abandonment and migration.

When a previously designed API no longer meets the requirements or has a major problem, we can mark it as obsolete and advise the user to migrate to another interface in the comments.

If it is a similar obsolete interface, it is best to use a new interface for internal coding to reduce the maintenance cost of backward compatibility.

For API of HTTP, you need to predefine the migrated error code. For example, in the HTTP specification, you can use 410 Gone to indicate that an interface is no longer supported.

"Review

API's Review is based on Code Review, which is commonly developed.

If the basic Code Review is not done well, the quality and stability of API can not be guaranteed.

You can use some tools to provide some reference reports for API's Review.

For example, you can use SonarLint to analyze code complexity, which can be a dangerous signal if the code complexity at the interface layer is high.

With the help of Java reflection and Clang syntax analysis, the current API interface list can be obtained and the interface change report can be generated, which is also helpful to reduce the exposure of useless interfaces.

In addition, the interface documents generated by automation tools are also an important part of Review.

"Test

In the testing process, we can pay attention to the stability of API through unit test.

Unlike agile developers who often modify test case, API's test case basically represents the stability of the interface. Therefore, when modifying the old case, you need to be particularly clear about whether the bug of the case itself or the interface behavior has changed.

Published by

We can provide a better experience for developers at different stages by distinguishing between dev and stable versions.

The dev version contains the latest features, but there is a risk of changes to the API interface. The stable version of API is stable, but the features are not necessarily up to date.

If the developer is still in the development process, you can choose the latest version of dev, based on the latest API development.

If the application is already online, you can choose to upgrade directly to the latest version of stable.

This is the answer to the question on how to ensure the stability of API design. I hope the above content can be of some help to you. If you still have a lot of doubts to be solved, you can follow the industry information channel to learn more about it.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Servers

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report