Best practices for open api application development and best practices for api application development
In the company's internal system, there will be some third-party Data Access scenarios, for example, in Ctrip's app, you can see iron's ticket, you can find the hotel where to go in the Meituan hotel list. This data is usually displayed on your client or H5 through open-api connection. Recently, we are working on an open-api project. In this scenario, a third party can call the http service provided by open-api to provide a third-party group buying service in our app. This article mainly summarizes some practical experience in system design.
System Design
The system includes two applications: one is a web application, the other is a server application, the web application provides http services externally, and the service application provides Internally called APIs. Why is it not completed in an application? This is to ensure that the project is clean and tidy. Web applications provide external APIs and do not directly deal with databases. server provides rpc services for web projects. The system design sequence diagram is as follows:
Figure 1
A third party calls the restful api provided by a web application and initiates a request according to the parameter format provided by us. After parameters are verified, open-api-web returns an error message based on the verification results or initiates an rpc call. Open-api-service stores data for each request to the database, including the request log and initial information of the group ticket. If no exception exists, the system asynchronously calls the single-System Service in the company and returns a preliminary processing result: the or error information in the Group Ticket Initialization is returned by the web application to a third party. When the asynchronous call result is returned, the rest api provided by the third party is called back to send the processing result.
Why is it necessary to asynchronously process the connection with the internal single-host system? This mainly takes into account the availability and speed of the api. In the process of uploading an image, it takes a long time to upload the image. If synchronous calling is adopted, the corresponding api time will be greatly increased, affecting the api availability.
Asynchronous
There are many ways to implement Asynchronization. In general, you should not complete everything in the same thread. The following methods have been taken into account:
1. encapsulate a task and submit a task to the thread pool through ExecutorService. The thread pool allocates a thread to process the logic that is connected to the single system.
2. Use spring event. Because spring synchronizes events by default, you can rewrite the multicastEvent method to implement Asynchronization.
3. When a message queue is used, the server saves the Group order locally, sends the message, and the server receives the message and processes the message.
The three methods are analyzed. 1 and 2 are close to each other, but they are essentially handled by another thread, but 2 is better than 1 because 2 achieves business decoupling, releasing and processing events can be independently developed. The publisher only needs to care about the publishing logic, while the receiver focuses on the connection with the internal system. Finally, we adopt the third method, because the third method is more stable because the message queue performs persistent processing on the message. When the application restarts or goes down, the message will not be lost, this ensures that each message can be processed.
For message processing, consider idempotent processing. For example, if a third party creates a group ticket without idempotence, duplicate creation may occur. Each time a creation request is received, the system first queries whether the data of the same group order has been saved in the database. If the data already exists, it is discarded. When updating the group list, we adopted the version number method. Assign a version number for each created group order. The initial value is 0. When an update request is received, the message producer first sends the message with the version number plus 1. After receiving the message, the consumer only accepts requests larger than the original version number compared with the version number in the database. If the requirements are met, the Group order is updated. After the update is successful, the latest version number is persistently added to the database. This ensures that requests are not processed repeatedly, but only the latest update requests are processed.
Exception Handling
For APIs with data addition, deletion, and modification, the processing result must be returned. How can I handle service logic errors or runtime exceptions during request execution? We have adopted a unified method for defining ErrorCode and exception handling. ErrorCode is an enumeration class that defines different service exceptions. Each enumeration includes the error code and error message msg, such as Parnert_NOT_FOUND (2001, "third-party does not exist "). At the same time, an exception BizException is defined. This exception is thrown when the service is executed and the error code is included. Finally, the Spring AOP technology is used to define a plane, proxy all the executed Business Code, catch exceptions in a unified manner, encapsulate different exceptions into Response, and then return response. What are the benefits of doing so? I think there are mainly two points: 1. The Exception code is collected into an enumeration class, so that the exception code can be defined and queried in a unified manner. 2. The exception handling code is processed in the aspect to prevent the exception handling code from being scattered everywhere, not conducive to maintenance.
When developing business code, you only need to care about the business logic and throw an exception when it is not as expected.
Security Control
Open APIs require strict third-party verification to prevent malicious users from using the company's internal systems at will. To ensure its security, we mainly consider three aspects:
1. Enter the basic information of the third party to the local database. When the Third Party calls the open api, it must input the information of the third party for verification;
2. the http request adopts the post method;
3. Signature Verification. Use symmetric encryption MD5 encryption to dynamically generate a signature.
Troubleshooting
How can I troubleshoot problems when a third party uses open APIs? First, you can know the processing result and cause of failure based on the code and msg returned by the api (encapsulated by the response object. What if I disagree with a request? We hope that the site can be restored to locate the problem. Therefore, I designed a log table to write down the path and parameters of each request, so that the third-party id can find the corresponding raw request data. The site was restored, and the problem was clear. At the same time, in the Local Group List table, the cause of the failure is also recorded for future reference.
Other general
Of course, there are still many things worth thinking about, such as traffic control and system monitoring. A seemingly simple function requires a lot of thinking to do well.