API first
API design common problems
Forgotten comments, comments usually describe API functions and parameter descriptions, as well as how to access them, and even give simple examples. Too detailed comments will bring certain adverse effects, such as adjustments to internal logic due to new requirements. However, due to the failure to update the API annotations in time, it will bring potential risks to the newly connected callers. Therefore, it is not only necessary to provide complete and clear annotations for the API. When the internal logic changes, as a developer, you usually need to evaluate the changes at the API level, including annotations.
The number of interfaces continues to expand. There are many reasons for the expansion of the number of interfaces. It may be an interface upgrade, but the old interface cannot be directly offline, so a new interface with similar functions will be provided; it may be that a new service is taken over due to lack of business understanding. Directly develop new interfaces in the face of new requirements; it may be that the interface classification is unreasonable, or the confusion of the data model leads to the confusion of the API division, the duplication of API functions, and finally multiple API interfaces in a scene can be met. This obviously should be avoided . Solving these problems needs to be based on a full understanding of the business. The following design principles will give solutions to such problems.
Lack of effective testing, many developers often ignore the testing of interfaces. Whether it is unit testing of internal logic details or interface level testing, it is an effective guarantee for service robustness. If the interface cannot be tested effectively, it is not only Withdraw cash responsibly, and often be troubled by online bugs.
Principles of API design
Simple: Among the object-oriented design principles, the first is the single responsibility principle, which is also applicable to API design. Our main object is the business model, and the API is a function that is open to the outside world after encapsulating internal logic. Ensuring the simplicity of the API and single responsibility can avoid solving the problem of expansion of the number of interfaces mentioned above. How can we achieve a single API responsibility? We need to be able to accurately identify the correlation and boundary between the interfaces when defining the interfaces. How to divide the API can be through the following perspectives:
According to business entities, different business entities use different interface classes
The interface of the query class and the modification class are separated; generally speaking, our data query scenario is much larger than the modification scenario, and there are various business scenarios for query. The data modification request usually comes from the business back-end personnel to modify the data. At this time, the business logic is usually more special (for example, there are a lot of additional data verification), so it is recommended to separate the modified class and the query API as much as possible, and even the business configuration back-end class query and the ordinary business query can be separated to adapt to their respective Business changes.
Concentration: A single interface scenario is based on business abstraction and focuses on a certain scenario and does not overlap each other, so as to ensure that the granularity of the interface is small enough, especially for basic services, the division of the interface granularity can ensure that the interface is pure and Independent of each other, so that changes in requirements will not involve too many interface changes (unless it is a major adjustment to the business model). In addition, it should be noted that the internal logic business data model (POJO class) and API data Models (DTO) sometimes differ, otherwise consumers may need to understand the business model of the service in order to use the interface correctly. This requires that in API design, developers need to clarify which data models should be provided to consumers, and even more on this premise Help us ensure the focus of a single interface.
Good notes
What comments should be included; the usage scenarios of the interface, the description of the parameters, the link address of the interface document can be given in the interface class description, which is convenient for the caller to view
The description of the parameter; including the meaning of the parameter, the type of the parameter is in accordance with the Javadoc link specification, whether the parameter is empty, and the special value description
Expiration description; if the interface has expired, an expiration description needs to be given. For Java, it is the @Deprecated annotation and the switch interface description is given. If conditions permit, the caller can be promoted to migrate the interface, and the old interface will be offline subsequently
The
only constant in scalability is change, and the interface will continue to evolve. We do not advocate excessive design in advance, but we must always maintain the scalability of the interface during the evolution process.
Multi-parameter structure and single-parameter structure. Generally speaking, if the parameters of an interface are less than three, it is recommended to use a multi-parameter interface, which is intuitive and concise. If an interface has many parameters and may often change later, in order to facilitate expansion And compatible, the parameters will be encapsulated into a class structure, remember to give a complete comment description for each field as well.
Class reuse nightmare Under a single parameter class structure, I often see multiple interfaces with obvious functional differences frequently reuse a structure, and even interface parameters and return values reuse a DTO. In order to ensure compatibility, they have to be in the same A DTO continues to add fields, and the maintenance cost continues to increase over time. This is an unreasonable type design. If you follow the principle of concentration, this problem can often be avoided.
compatibility
When interface logic or parameters change, it is necessary to maintain compatibility with the old interface. This is one of the principles that must be followed when API changes, and compatibility must be verified through interface testing.
Whether to add a new interface, when faced with a new requirement, in order to avoid direct modification of the old interface, some developers will provide the new interface uniformly. If it is not a major change in logic, this will improve the API Maintenance cost. If the API is not refactored in the future, the new maintenance cost will be much greater than the initial development cost saved. For example, if a parameter needs to be validated, then we need to modify the API implementation of both interfaces. , And repetitive code, and our scope of influence has become two interfaces, so the expansion of the scope of influence also brings more potential risks. Of course, in certain scenarios, such as major adjustments in interface logic, API refactoring, etc., a better way is to provide new interfaces and encourage service consumers to use the new API, and finally slowly offline the old API. To follow the principle of simplicity and focus.
Perfect test
Unit testing, perfect unit testing can ensure the robustness of the code, discover and solve potential bugs in the coding phase in advance, unit testing is a necessary ability for developers.
Interface and scenario testing. Interface testing includes internal logic verification, abnormal input, concurrency and other scenarios to verify a single interface. If you want to perform a complete logic verification on the API, developers need to construct complete test data (usually including scheme.sql and data.sql file), especially for basic services, it is necessary to combine multiple interfaces in some complex business scenarios to complete a scenario test, and perform Assert confirmation on the intermediate data and output, which will also code a certain test code Maintenance costs require developers to weigh the pros and cons.
Paying attention to
well- documented comments and documentation can reduce most of the communication with service consumers, and also avoid some wrong interface calls. No one wants to waste a lot of saliva on IM tools every time or need to ask face to face to know how to use the API correctly, and no developer is willing to repeatedly answer how to call the provided interface every day. For interface documentation, it can be a simple method such as Javadoc, or centralized management through wiki, it can be markdown documentation, there are also many open source systems such as Swagger, yapi, eolinker, etc.; the architecture of microservices is greatly enhanced The cost of communication is also a drawback of the microservice architecture, but the proper use of tools can reduce unnecessary communication.
to sum up