Experience of APP architecture design: interface design


How to design the communication interface between app and server well needs to be considered. Based on my experience, I would like to make some summary and share in order to attract more jade.

Design of security mechanism

Now, most app interfaces areAdopt restful architectureOne of the most important design principles of restful is,The interaction between client and server is stateless between requestsThat is to say, when it comes to user status, authentication information is carried with each request. In terms of implementation, most of them areUsing token authentication methodThe general process is as follows:

  • After the user successfully logs in with the password, the server returns a token to the client;

  • The client saves the token locally and sends the token back to the server when it initiates subsequent related requests;

  • The server checks the validity of the token and returns data if it is valid. If it is invalid, it can be divided into two situations:

    • If the token is wrong, the user needs to log in again to obtain the correct token

    • When the token is expired, the client needs to send another authentication request to obtain a new token

However, this authentication method has a security problem: when the login interface is hijacked, the hacker will get the user password and token, and then can do anything to the user. Only by changing the password can the user regain control.

How to optimize?The first solution is to use HTTPS。 HTTP adds SSL security protocol on the basis of HTTP, and automatically compresses and encrypts the data. In a certain program, it can prevent monitoring, hijacking and retransmission, and the security can be improved a lot. However, SSL is not absolutely secure and may be hijacked. In addition, the configuration of the server for HTTPS is relatively complex, and it needs to apply for a certificate from Ca, and it is generally charged. Moreover, the efficiency of HTTPS is relatively low. Generally, only systems with high security requirements will adopt HTTPS, such as banks. Most apps with less security requirements still use HTTP.

Our current practice is to add signatures to each interface。 Each time the interface is requested, the key and all parameters are combined into a source string. The signature value is generated according to the signature algorithm. When sending the request, the signature is sent to the server for verification. Similar implementation can refer to oauth1.0 signature algorithm. In this way, the hacker does not know the key and the signature algorithm. Even if the login interface is intercepted, the subsequent request cannot be operated successfully. However, because the signature algorithm is cumbersome and error prone, it is only suitable for internal interfaces. If your interface is an open API, it is not suitable for this signature authentication method. It is recommended to use oauth2.0 authentication mechanism.

We also assign an appkey to each end, such as Android, IOS and wechat. Each end is assigned an appkey and a key. An error will be reported for a request that has not passed an appkey, and an error will also be reported for a request that has passed the wrong appkey. In this way, the security aspect adds another layer of defense, and at the same time, it is convenient to do some different processing strategies for different terminals.

In addition, now more and more apps cancel password login, and use mobile phone number + SMS verification code login method. I also use this login method in the current project. There are several advantages to this login method:

  • There is no need to register, no need to change the password, and no need to reset the password because of forgetting the password;

  • Users no longer need to remember the password and are not afraid of password disclosure;

  • Compared with password login, its security is improved obviously.

Design of interface data

Generally, the data of the interface is transmitted in JSON format. However, it should be noted that there are only six data types for JSON values:

  • Number: integer or floating point number

  • String: String

  • Boolean: true or false

  • Array: the array is contained in square brackets []

  • Object: the object is contained in braces {}

  • Null: null type

Therefore, no more than these six data types can be transmitted. Previously, we have tried to transfer the date type, which will be converted to a string similar to “09:17:42 GMT + 08:00, January 7, 2016”. This will cause problems during conversion. Different parsing libraries may have different parsing methods, some may be confused, and some may be directly abnormal. To avoid errors, you must do special processing and do the parsing manually. To eradicate this problem, the best solution is to represent dates in milliseconds.

In addition, in previous projects, “true” and “false” of strings, or numbers of strings, or even “null” of strings, led to parsing errors, especially “null”, which led to app crash. Later, it took a long time to find out that it was caused by this problem. This is because the server does not process the data well, resulting in some data converted into strings. Therefore, on the client side, we can not fully trust that the data returned by the server is correct, and all exceptions need to be handled accordingly.

The data structure returned by the server is generally:

    message: "success"
    data: { key1: value1, key2: value2, ... }

Code: status code, 0 means success, non-0 means various errors

Message: describes the information. It is “success” in case of success and error in case of error

Data: the data returned on success. The type is object or array

Different status codes need to be defined for different errors. Errors belonging to the client and errors from the server should also be distinguished. For example, 1XX indicates the error of the client and 2XX indicates the error of the server. Here are some examples:

  • 0: success

  • 100: request error

  • 101: missing appkey

  • 102: missing signature

  • Missing parameter: 103

  • 200: server error

  • 201: service not available

  • 202: server is restarting

Error messages are generally used for two purposes: one is to see what errors are when debugging by client developers; the other is to display them directly to users as app error prompts. It is mainly displayed to users as app error prompts. So, most of them are short messages.

The data field only returns data when the request is successful。 The data type is limited to object or array. When the data required by the request is a single object, the object is returned. When the data required by the request is a list, it is an array of an object. What should be noted here is that do not pass data into strings or numbers. Even if the request requires only one data, such as token, the returned data should be:

data: { token: 123456 }

data: 123456

Design of interface version

The interface can’t be immutable, and it will always change in the continuous iteration. There are several types of interface changes:

  • Data changes, such as adding data types not supported by the old version

  • Parameter changes, such as adding new parameters

  • The interface is abandoned and the interface is no longer used

In order to adapt to these changes, the interface version must be designed. Generally, there are two ways to realize it

  • Each interface has its own version. Generally, a version parameter is added to the interface.

  • The whole interface system has a unified version. Generally, the version number is added to the URL, such as http://api.domain.com/v2 。

In most cases, the first method is adopted. When an interface is changed, the version number is superimposed on the interface and the old version is compatible. The version of the new version will be passed in when the new version of app is developed and transferred.

If the foundation of the entire interface system changes, for example, the microblog API will be upgraded from oauth1.0 to oauth2.0.

Sometimes, changes in one interface will affect other interfaces, but you may not find them when you do it. Therefore, it is better to have a complete testing mechanism to ensure that every interface change can be tested to all relevant levels.

Write it at the end

So much for the moment about interface design. If you feel that there are omissions or what needs to be optimized after reading, you are welcome to discuss them together.

The blogger agrees with the view of this article, and the current project is also using the same interface design. The summary of this paper is very good, so it is transferred to this blog for collection. If there is any copyright infringement problem, please contact the blogger.

Reprinted from Keegan steel

Link to the original text: http://keeganlee.me/post/architecture/20160107