Current location - Quotes Website - Personality signature - What is a good API and design process and design principles?
What is a good API and design process and design principles?
Safety is an eternal topic. For Web services based on WSDL and SOAP, we have security specifications such as WS-Security to guide the realization of security requirements, such as authentication, authorization and identity management. So, does RESTful API have a mature specification or implementation framework? How to ensure the security of RESTful API?

How to control the version of RESTful API, please share what you think is practical?

Are the verbs given in HTTP 1. 1 specification sufficient for designing RESTful API? Do you expand your verbs in actual projects? When do you need to expand?

What are the most valuable features of JAX-RS 2.0 released in May this year for the design of RSTfulAPI? What problem is it used to solve?

Can you recommend a practical RESTful API development framework for InfoQ readers and explain your reasons?

HTTP2.0 specification is being worked out. What do you expect from it?

InfoQ: what is a good RESTful API? I believe everyone has their own criteria. So, what characteristics do you think a good RESTful API should have?

Kingsceo: A good RESTful API should have the following characteristics:

This API should be browser-friendly and can be well integrated into the Web, not incompatible with the Web.

Browser is the most common and universal REST client. A good RESTful API should be able to use browser +HTML (no programming language is needed) to complete all tests. Such an API can also be easily tested by using various automated Web function testing and performance testing tools. Web front-end applications (RIA applications based on browser, mobile applications, etc.). ) You can also easily combine the functions of multiple RESTful API to build a Mashup-like application.

The resources contained in this API and the operations on the resources should be intuitive and easy to understand, in line with the requirements of the HTTP protocol.

REST development is also called "resource-oriented development", which shows that the abstraction of resources is the core content of designing RESTful API. RESTful API modeling process is similar to object-oriented modeling, with nouns as the core. These nouns are all resources, and any abstract concept that can be named can be defined as resources. HTTP protocol is not a transport protocol, but actually provides a unified interface for operating resources. Any operation of resources should be mapped to several limited methods of HTTP (four commonly used methods are GET/POST/PUT/DELETE, and the uncommon PATCH/HEAD/OPTIONS method). Therefore, the modeling process of RESTful API can be regarded as an object-oriented modeling process with unified interface constraints.

According to the provisions of the HTTP protocol, the GET method is secure and idempotent, the POST method is neither secure nor idempotent (it can be used as a wildcard method for all write operations), and the PUT and DELETE methods are both insecure but idempotent. Map the operation of resources to these four methods reasonably, and don't overuse one method (such as GET method or POST method) or add so many operations that the four methods of HTTP are not enough.

If you find that there are too many operations on resources that HTTP methods are not enough, you should consider designing more resources. There is no harm in designing more resources (and corresponding URIs) for RESTful API.

This API should be loosely coupled.

The design of RESTful API includes three levels: resource abstraction, unified interface and hypertext drive. It is these three levels that ensure the loose coupling of RESTful API.

When designing Internet-oriented API, loose coupling becomes a "must have" strong demand. The tightly coupled API is very fragile, and once released, neither the server nor the client can continue to evolve. Especially on the server side, the published interface has not changed at all. After being changed, almost all client applications can't work normally immediately. The architectural style of REST is the antidote of tightly coupled API. This topic can be discussed in depth, so I won't expand it here. Interested readers can refer to REST actual combat.

The presentation format used in this API should be a universal format.

In RESTful API, the operation of resources is done indirectly by passing the expressions of resources between the server and the client. Resources can be represented in many formats, and the format of resource representation in response and request will be different. The common resource expression formats in GET/POST response are HTML, XML and JSON;; The formats of resource expressions in POST/PUT requests include standard HTML form parameters, XML and JSON.

These common expression formats are very easy to handle and are supported by a large number of frameworks and libraries. So unless there are reasonable requirements, you usually don't need to use a custom private format.

Use HTTP response status codes to indicate various error conditions.

HTTP response status code is a standard mechanism used to indicate error conditions in the unified interface of HTTP protocol. The response status code is divided into two parts: status code and reason stage. Both parts can be customized, or you can use standard status codes and customize only the reason stage.

If a so-called "RESTful API" returns a 200 OK response to any request and returns an error message in the message body of the response, this practice obviously does not meet the basic requirements of the REST architecture style of "ensuring semantic visibility of operations".

This API should be HTTP cache friendly.

Making full use of HTTP cache is the basis of the scalability of RESTful API. HTTP protocol is a hierarchical architecture, and many intermediate components can be inserted from the user agents at both ends to the source server. Cache can be set in many places in the whole HTTP communication chain. HTTP protocol has a good caching mechanism, which is divided into two groups: expiration model and verification model. If the API designer doesn't consider how to use HTTP cache at all, there will be many problems in the scalability of this API.

Li Jianye: First of all, I generally understand the concept of REST as a REST-style architecture, but now the most widely recognized in practice is HTTP, which is an implementation of REST, so RESTful API can also refer to an API based on HTTP-of course, even if it is not in a strict sense, the API itself should strive to follow the REST-style architecture.

In my opinion, the most important point of a RESTful API should be "the less prior information, the better", which is also my criterion for judging a good RESTful API.

For example, HTTP verbs, in practice, people may often struggle with the effective use of HTTP verbs, but this is not particularly important-unless you understand the value of doing so. The most important thing about HTTP verbs is that they are behaviors clarified by standards. In other words, if our "customers" follow the convention, there is no need to invent new verbs and add "transcendental information". However, the so-called "prior information" is the caller of the API for the client. For some enterprise internal systems or some traditional systems, the "calling client" of these systems is not a browser but another system, because the "resources" are very stable. At this time, if I forcibly correspond to HTTP verbs, it will become extra "prior information", so I am not too rigid.

Another example is the Content-Type in Response, which is sometimes ignored by novices, but it is actually very important, because generally APIs involving collaboration between systems often don't use ordinary text, and json is more common to express complex structures, which is different from the usual default understanding (the default is generally considered as text/plain and text/html). So if you forget to distinguish Content-Type in the API, the subsequent support for multiple types of client access will become a trap (this problem we have encountered many times). This difficulty can be avoided if we check whether prior knowledge is added from the beginning (the default content type is simple or the content type is allowed to be specified).

Ding Xuefeng: First of all, we should correctly use the unified interface of HTTP, such as HTTP verbs. If you post indiscriminately, there is obviously room for improvement.

Secondly, resources have appropriate granularity, and whether the granularity of resources is reasonable can be judged from three aspects-the efficiency of the network, the size of the expression and the ease of use of the client;

Finally, the design of the expression, besides the text content of the expression, also contains URIs and links, which is the standard to judge the quality of a RESTful API.

Ma Jun: In my opinion, a good API standard is to make full use of the characteristics of HTTP protocol and regard HTTP as a transport protocol, not a transport protocol. Including but not limited to: using various verbs of HTTP to clarify operations; Includes content negotiation, which can select the most suitable media type, language, character set and coding performance according to the parameters provided by the request header; Use different return codes to describe various states. But in fact, I have seen many claims that RESTful API, whether domestic or foreign, can meet these conditions. The API provided by parse.com is a better RESTful API I have ever seen, which can be used as an example for reference.

InfoQ: Security is an eternal topic. For Web services based on WSDL and SOAP, we have security specifications such as WS-Security to guide the realization of security requirements, such as authentication, authorization and identity management. So, does RESTful API have a mature specification or implementation framework? How to ensure the security of RESTful API?

Kingsceo: Ensuring the security of RESTful API mainly includes three aspects:

A) verify the identity of the customer

B) Encrypt sensitive data to prevent tampering.

C) authorization after authentication

There are several common methods to authenticate clients:

Add signature parameters to the request.

Assign a key to each accessor and specify the signature calculation method. The signature parameter must be added to the visitor's request. This method is the simplest, but to ensure the safe storage of access keys, we should also pay attention to prevent replay attacks. Its advantage is easy to understand and implement, but its disadvantage is that it needs to bear the burden of keeping the key safely and updating it regularly, which is not flexible enough, and it is difficult to update the key and update the signature algorithm.

Use standard HTTP authentication mechanism.

HTTP basic authentication has low security and must be used with HTTPS. HTTP digest authentication can be used alone and has a moderate degree of security.

HTTP digest authentication mechanism also supports inserting user-defined encryption algorithm, which can further improve the security of API. However, in the Internet-oriented API, inserting custom encryption algorithm has not been widely used.

This method needs to ensure the safe storage of the triple information of "security domain-username-password" of the access party, and also pay attention to preventing replay attacks.

Advantages: based on standards, it has been widely supported (a large number of HTTP server-side and client-side libraries). The responsibility of server-side HTTP authentication can be undertaken by Web Server (such as Nginx), App Server (such as Tomcat) and security framework (such as Spring Security), which is transparent to application developers. HTTP authentication mechanism (RFC 26 17) embodies the design principle of "separating concerns" and keeps the visibility of operational semantics.

Disadvantages: The security of this mechanism based on simple user name and password cannot be higher than that based on asymmetric keys (such as digital certificates).

Use OAuth protocol for authentication.

The OAuth protocol is applicable to the case that external applications are authorized to access the resources of this site. Compared with HTTP digest authentication, encryption mechanism is more secure. It should be noted that OAuth authentication and HTTP digest authentication are not substitutes for each other, and their application scenarios are different. OAuth protocol is more suitable for providing authorization for end-user oriented API, such as obtaining Weibo information belonging to users and so on. If the API is not oriented to the end-user dimension, such as storage services such as Qi Niu Cloud Storage, this is not a typical application scenario of OAuth protocol.

In order to encrypt sensitive data and prevent tampering, common practices are:

Deploy SSL infrastructure (namely HTTPS), and the transmission of sensitive data is all based on SSL.

Only encrypt some sensitive data (such as card number+password of prepaid card), and add some random numbers as encryption salt to prevent data from being tampered with.

Authorization after authentication is mainly controlled by the application. Usually, some authorization mechanisms based on roles and user groups should be implemented, and there are many frameworks (such as Spring Security) in this respect, but most development teams still prefer to implement related functions themselves.

Li Jianye: I don't think security is a problem that RESTful API needs to consider. Actually, I think these are two orthogonal questions. Of course, if RESTful API is used to provide authentication, authorization and identity management, it can be considered as a relationship between the two parties, but it seems to be no different from other styles of API design and does not deserve special attention.

However, at the specific design level, there seems to be some problems in the "orthogonal point" between the two, because REST is an architectural style that advocates the principle of state independence, and authentication and authorization are usually based on third-party solutions, so the problem of violating state constraints often occurs. I have no special idea about this place. Of course, this difficulty has little to do with the original question.

As for the WS- family protocol, I don't know much about it, so I can't participate in the discussion.

Ding Xuefeng: For RESTful API, ordinary security measures can continue to be used. For example, in order to prevent tampering, all parameters can be signed; In order to prevent replay attacks, you can add a one-time token or a token that is valid for a short time in the request; Encrypting content can prevent data leakage ...; For DDoS attacks, various HTTP traffic cleaning strategies can continue to play a role, because this is a basic HTTP request.

In terms of authorization and authentication, OAuth 2.0 has basically matured and been widely used. If possible, it is a good choice to access the third-party account system, such as Google and Facebook. Of course, China also has several candidates.

Ma Jun: I personally think that the security of RESTful can be divided into several levels. In the occasion of high security requirements, the security of the network layer can be guaranteed by encryption protocols such as HTTPs, the security of the application layer can be authenticated by OAuth, and the access authorization of resources can only be realized by applications.

InfoQ: How to control the version of RESTful API, please share your practice?

Kingsceo: A simple and practical method is to insert the version number directly into the URI, which allows multiple versions of the API to run in parallel.

Another method is to add customized header information to the HTTP request, indicating the version number used. However, this method is actually not friendly to the browser, and it cannot be tested simply by browser +HTML.

Li Jianye: At present, a better way is to add version information to the uri design. Other methods are not as practical as this one.

Ding Xuefeng: Personally, I think the best version is that there is no obvious version. When modifying published services, we should try our best to be compatible, including URIs, links and various expressions. The most important thing is not to destroy existing customers when expanding. For example, if you change a parameter, you can choose to be compatible with both old and new inputs, or you can leave the old parameter unchanged and provide a new parameter, which must be explained in the document. It is not recommended for new users to continue using the previous parameter.

If incompatible changes must be made, you can choose to mark a different version number, and then you can choose to add version information in the path or parameter. There are also methods to add HTTP headers, but it is a little inconvenient to call them. The first two methods are recommended.

Ma Jun: The version of RESTfulAPI is upgraded to be as compatible as possible with the previous version, to ensure that the original API can work normally, and to jump to new resources through HTTP 30 1 Another practical method is to keep the version number in the url and provide multiple versions for the client, such as v 1.rest.com or rest.com/v1.

Infoq: Are the verbs given in the specification of http1.1sufficient for designing RESTful API? Do you expand your verbs in actual projects? When do you need to expand?

Kingsceo: This question depends on how designers view and design resources. If the resource abstraction is done well, any operation of the resource can usually be mapped into four types of CRUD. In most cases, the four categories of CRUD are complete for operating resources. The four methods of HTTP GET/POST/PUT/DELETE are enough for CRUD operation, and the mapping relationship is create-post/retrieve-get/update-put/delete-delete.

We usually don't choose to create verbs ourselves, which requires more learning costs for client developers. If too many operations are defined on resources, we will choose to split more resources.

Li Jianye: Generally speaking, it is enough. Sometimes some "insufficient" scenarios are because we don't design reasonable resources, such as batch operation. However, as mentioned above, for some internal and traditional (so the model is stable and known) systems, API providers and callers will have their own fixed verb lists, so there is no need to stick to this at this time. Besides, I don't recommend expanding verbs. Once the verb is expanded, it has actually destroyed what I said before * "The less prior information, the better" *, so the cost of expanding the verb is not much different from the cost of redesigning the verb. Based on this consideration, I suggest keeping the verbs unchanged as much as possible unless you want to redesign the verb list.

Ding Xuefeng: Generally speaking, the commonly used HTTP verbs are enough, and you don't need to expand the verbs yourself. In fact, the most commonly used are GET, POST, DELETE, PUT, HEAD, OPTIONS and TRACE, which are rarely used. If you can't find a suitable verb at the moment, you can use GET for safe idempotent operation, and POST for others. You can think about it a little when designing resources.

Ma Jun: In my actual project, I only used four verbs: POST, PUT, DELETE and GET.

InfoQ: What are the most valuable features of JAX-RS 2.0 released in May this year for the design of RSTfulAPI? What problem is it used to solve?

Kingsceo: Bill Burke, the project leader of RESTEasy, a REST development framework, wrote an article about JAX-RS 2.0 last year.

I agree with Bill in his article. In JAX-RS 2.0, the three most important parts are:

A) Client API- used to standardize the development mode of JAX remote sensing client.

B) Server-side asynchronous HTTP-used to realize server-side push function without relying on inefficient polling.

C) Filters and interceptors-used to separate concerns and separate logic such as authentication and logging from business logic, so as to better realize code reuse.

The contents of these three parts are very useful for developers. Developing according to JAX-RS specification can ensure the portability of server-side and client-side codes.

Li Jianye: I personally pay attention to this part of asynchronous API, mainly because there will be more and more streaming media services, and this kind of support will be needed in large quantities.

InfoQ: Can you recommend a practical RESTful API development framework for InfoQ readers and explain the reasons?

Kingsceo: I won't answer this question in detail. Different programming languages have different REST development frameworks and different support for REST. There are various requirements and alternative development frameworks for developing RESTful API. Maintaining diversity is the basis of prospering the ecological environment. Like Java, there are many frameworks that support JAX-RS specification, such as Jersey, RESTEasy, Restlet, Apache CXF, Spring MVC that does not support JAX-RS specification and so on. These frameworks are doing well at present. I have no preference for the choice of framework. The best practices of RESTful API design should be universal, not necessarily dependent on a specific development framework.

Li Jianye: Sorry, I don't pay much attention to this and I don't recommend it, but I can explain why I'm not interested in the RESTful API framework.

REST, as an architectural style, has a great influence on our system development, but these influences are generally aimed at architecture (such as state independence) or design (such as resource identification), so once it is implemented, the main work is basically over, and the development framework can only simplify programming (in contrast, some frameworks can also play a role in guiding design), and because RESTful abstracts verbs, the level of implementation is the same as API specifications.

Of course, we can't develop directly based on servlet/rakc/wsgi, but general programming languages will provide some simple url routing/matching strategies, which are enough for us to use. In addition, some frameworks can help us generate all verb support, but this is not necessarily a good thing. I generally prefer on-demand implementation-with re-support, I don't need to care too much about the support of the development framework for RESTful.

Ding Xuefeng: As I am a supporter of Spring and have been using Spring in my work, I tend to choose Spring MVC when choosing a framework (not to say that other frameworks are not good, there are some subjective factors here). If you must choose other frameworks, you should also choose a framework that can be easily integrated with Spring. If Spring is already used in the project, there is no reason not to choose Spring MVC. In view of the high occurrence rate of Spring in various projects at present, I believe Spring MVC will generally be chosen.

In the maturity model of REST, the third layer is HATEOAS. At present, Spring also provides the Spring Hateoas subproject, which enhances the support for links and resources.

Ma Jun: I'm currently using Spray in the actual project, which is an open source REST/HTTP toolkit and the underlying network IO package, which is based on Scala and Akka. Lightweight, asynchronous, non-blocking, based on actor mode, modularity and testability are the characteristics of Spray.

InfoQ: The specification of HTTP 2.0 is under development. What do you expect from it?

Kingsceo: My expectations include two aspects: what to do and what not to do.

What should the HTTP/2.0 specification do?

Compatible with HTTP/ 1. 1 protocol. Compatibility means that the two can coexist, and the client application can freely choose whether to use HTTP/2.0 or HTTP/ 1. 1 according to the capabilities of the server, and the selection process is transparent.

Improve the syntax of operation semantic expression in HTTP protocol (as a unified interface of resources) and improve the efficiency of network transmission.

Better modularity, so that the implementation of HTTP/2.0 protocol can be better modularized. The application can choose the appropriate modules as needed, instead of all or nothing.

Discard some rarely used parts of the HTTP/ 1. 1 protocol, such as sending requests by pipeline.

Add more verbs to adapt to other scenes except CRUD.

What HTTP/2.0 specification should not do:

HTTP/2.0 protocol should not take the underlying data encryption mechanism (SSL) as a necessary option.

HTTP/2.0 protocol should not break away from the constraints of REST architecture style, especially to ensure the visibility of operational semantics to intermediate components.

In the above two aspects, Roy Fileidng had a heated debate with Mike Belshe, the designer of SPDY protocol. For details, please see: Roy Fielding talks about the Google SPDY agreement.

Li Jianye: I don't pay much attention to this specification. I wonder if streaming media will be supported. At present, all I know is the simple support for chunk, and the real streaming needs to distinguish between data channel and control channel, even if it is logical, it has a great influence on REST style. Considering the development potential of streaming media services in the future, I especially look forward to the progress of the industry in this regard.

Ding Xuefeng: HTTP 2.0 is largely based on Google's SPDY. Personally, I hope this specification can be compatible with HTTP 1. 1 at first. If the user only knows 1. 1, then 2.0 can be gracefully "degraded"; Secondly, I hope 2.0 can bring better performance, and SPDY has improved in this respect. I hope HTTP 2.0 can make persistent efforts. Finally, I hope that this specification can be finalized with a best practice, and correctly guide people to use HTTP 2.0 reasonably.

Ma Jun: I haven't studied it. It is estimated that even if it comes out, 1. 1 still has a long life cycle and will not be replaced soon.