Summary of Practice and Thinking of Microservice API Design

As microservices become more and more popular, more and more companies have begun to implement microservice architecture. Compared with a single application architecture, microservices split the complexity and break it down into more granular applications. It greatly reduces the complexity of a single service in development. Developers only need to focus on a single business scenario programming. From a technical development perspective, the amount of code for a single service is greatly reduced. From a business perspective, the reduction in business complexity reduces demand However, the overall business complexity still exists. When we need to access or rely on other services, usually as the access party, we do not need to understand the service provider’s business deeply. At this time, the API becomes the developer The language of communication between. Good API design can greatly reduce communication costs, and sometimes can replace documents, especially for basic services. The scalability of services is sometimes reflected in the scalability of APIs. I have participated in a foundation The business upgrade of business microservices, due to the lack of clear division of APIs in the old version and the repetitiveness of some APIs, most of the APIs have to be refactored later (replaced with new versions of APIs), which will continue only at the stage of service consumer upgrades Over the course of 1-2 months, during this process, I continued to think about some problems in API design and which principles should be followed.


API first

191b732f7e768b81d29b21463e8f5694.png


Under the big wave of agile development, products usually require rapid iteration. Faced with a new requirement, if a new interface needs to be developed, usually after the table structure is designed, the developer needs to complete the API design and deliver it to the consumer (ie The caller or relying party of the service, the rest of the text means this meaning), before the technical joint debugging, the consumer can complete the debugging with the Mock interface. So generally speaking, the API is delivered with the service first, and then the coding, testing, and debugging are completed. Of course, due to the requirements details, technical implementation, it may be found that the requirements need to be adjusted during the implementation process, or the API interface adjustment, the initial version of the API may be immature, resulting in us often in the API adjustment or evolution process in the API maintenance There are many omissions, so the maintenance after the initial delivery of the API is a continuous work.


API design common problems

191b732f7e768b81d29b21463e8f5694.png


In the process of our API design, due to lack of experience, or due to multiple handovers, or due to multiple demand changes, the service API is slowly corrupted, causing the following 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

191b732f7e768b81d29b21463e8f5694.png


Simple and focused
  • 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

191b732f7e768b81d29b21463e8f5694.png


As a bridge between microservices, API design and maintenance are a very important part of the microservice architecture. Each developer not only needs good code specifications, but also needs to establish and comply with API design specifications. API design ability as a part of soft power in microservice architecture requires developers to have a certain amount of design experience accumulation. At the same time, only continuous thinking and summarization can have a deeper understanding.


Guess you like

Origin blog.51cto.com/14992974/2547587