REST Representational state transfer REST Resource Naming Guide Never use CRUD function names in URIs

时间:2022-06-28 07:30:16

怎样用通俗的语言解释什么叫 REST,以及什么是 RESTful? - 知乎  https://www.zhihu.com/question/28557115

REST Representational state transfer    REST Resource Naming Guide   Never use CRUD function names in URIs

REST Representational state transfer    REST Resource Naming Guide   Never use CRUD function names in URIs

大家都知道"古代"网页是前端后端融在一起的,比如之前的PHP,JSP等。在之前的桌面时代问题不大,但是近年来移动互联网的发展,各种类型的Client层出不穷,RESTful可以通过一套统一的接口为 Web,iOS和Android提供服务。另外对于广大平台来说,比如Facebook platform,微博开放平台,微信公共平台等,它们不需要有显式的前端,只需要一套提供服务的接口,于是RESTful更是它们最好的选择。

作者:覃超
链接:https://www.zhihu.com/question/28557115/answer/48094438
Server的API如何设计才满足RESTful要求?
首先是简洁版里面的那几点。外加一些附带的 best practices:
1. URL root:
https://example.org/api/v1/*
https://api.example.com/v1/*2. API versioning:
可以放在URL里面,也可以用HTTP的header:
/api/v1/
3. URI使用名词而不是动词,且推荐用复数。
BAD
  • /getProducts
  • /listOrders
  • /retrieveClientByOrder?orderId=1

GOOD

  • GET /products : will return the list of all products
  • POST /products : will add a product to the collection
  • GET /products/4 : will retrieve product #4
  • PATCH/PUT /products/4 : will update product #4

4. 保证 HEAD 和 GET 方法是安全的,不会对资源状态有所改变(污染)。比如严格杜绝如下情况:
GET /deleteProduct?id=1
5. 资源的地址推荐用嵌套结构。比如:
GET /friends/10375923/profile
UPDATE /profile/primaryAddress/city6. 警惕返回结果的大小。如果过大,及时进行分页(pagination)或者加入限制(limit)。HTTP协议支持分页(Pagination)操作,在Header中使用 Link 即可。
7. 使用正确的HTTP Status Code表示访问状态:HTTP/1.1: Status Code Definitions
8. 在返回结果用明确易懂的文本(String。注意返回的错误是要给人看的,避免用 1001 这种错误信息),而且适当地加入注释。
9. 关于安全:自己的接口就用https,加上一个key做一次hash放在最后即可。考虑到国情,HTTPS在无线网络里不稳定,可以使用Application Level的加密手段把整个HTTP的payload加密。有兴趣的朋友可以用手机连上电脑的共享Wi-Fi,然后用Charles监听微信的网络请求(发照片或者刷朋友圈)。
如果是平台的API,可以用成熟但是复杂的OAuth2,新浪微博这篇:授权机制说明

各端的具体实现
如上面的图所示,Server统一提供一套RESTful API,web+ios+android作为同等公民调用API。各端发展到现在,都有一套比较成熟的框架来帮开发者事半功倍。

REST架构资料 - 简书
http://www.jianshu.com/p/ee8059f3e097

w

http://www.infoq.com/cn/articles/webber-rest-workflow?utm_source=infoq_en&utm_medium=link_on_en_item&utm_campaign=item_in_other_langs

https://www.infoq.com/articles/webber-rest-workflow

http://kb.cnblogs.com/page/91827/

"那么,Web和REST之间究竟有什么关系呢?我们接下来将聊聊组成Web的几大基础技术,URI(统一资源标识符,用来标识资源)、HTTP(超文本传输/转移协议,用来操作资源)、Hypertext(超文本,用来描述资源的内容与状态,我们可以用HTML、XML、JSON或者自定义格式的文本来描述任何一个资源)

"

“跟大部分餐饮企业一样,星巴克也主要致力于将订单处理的吞吐量最大化。顾客订单越多,收入就越多。为此,他们采取了异步处理的办法。你在点单时,收银员取出一只咖啡杯,在上面作上记号表明你点的是什么,然后把这个杯子放到队列里去。这里的队列指的是在咖啡机前排成一列的咖啡杯。正是这个队列将收银员与咖啡师解耦开,从而,即便在咖啡师一时忙不过来的时候,收银员仍然可以为顾客点单。他们可以在繁忙时段安排多个咖啡师,就像竞争消费者模式(Competing Consumer)里那样。”

"Starbucks, like most other businesses is primarily interested in maximizing throughput of orders. More orders equals more revenue. As a result they use asynchronous processing. When you place your order the cashier marks a coffee cup with your order and places it into the queue. The queue is quite literally a queue of coffee cups lined up on top of the espresso machine. This queue decouples cashier and barista and allows the cashier to keep taking orders even if the barista is backed up for a moment. It allows them to deploy multiple baristas in a Competing Consumer scenario if the store gets busy."

REST Resource Identifier (URI) Naming – REST API Tutorial https://restfulapi.net/resource-naming/

REST Resource Naming Guide

In REST, primary data representation is called Resource.  Having a strong and consistent REST resource naming strategy – will definitely prove your one of best design decisions in long term.

The key abstraction of information in REST is a resource. Any information that can be named can be a resource: a document or image, a temporal service (e.g. “today’s weather in Los Angeles”), a collection of other resources, a non-virtual object (e.g. a person), and so on. In other words, any concept that might be the target of an author’s hypertext reference must fit within the definition of a resource. A resource is a conceptual mapping to a set of entities, not the entity that corresponds to the mapping at any particular point in time.Roy Fielding’s dissertation

A resource can be a singleton or a collection. For example, “customers” is a collection resource and “customer” is a singleton resource (in a banking domain). We can identify “customers” collection resource using the URI “/customers”. We can identify a single “customer” resource using the URI “/customers/{customerId}”.

A resource may contain sub-collection resources also. For example, sub-collection resource “accounts” of a particular “customer” can be identified using the URN “/customers/{customerId}/accounts” (in a banking domain). Similarly, a singleton resource “account” inside the sub-collection resource “accounts” can be identified as follows: “/customers/{customerId}/accounts/{accountId}”.

REST APIs use Uniform Resource Identifiers (URIs) to address resources. REST API designers should create URIs that convey a REST API’s resource model to its potential client developers. When resources are named well, an API is intuitive and easy to use. If done poorly, that same API can feel difficult to use and understand.

The constraint of uniform interface is partially addressed by the combination of URIs and HTTP verbs, and using them in line with the standards and conventions.

Below are a few tips to get you going when creating the resource URIs for your new API.

REST Resource Naming Best Practices

Use nouns to represent resources

RESTful URI should refer to a resource that is a thing (noun) instead of referring to an action (verb) because nouns have properties as verbs do not – similar to resources have attributes. Some example of resource are:

  • Users of the system
  • User Accounts
  • Network Devices etc.

and their resource URIs can be designed as below:

http://api.example.com/device-management/managed-devices
http://api.example.com/device-management/managed-devices/{device-id}
http://api.example.com/user-management/users/
http://api.example.com/user-management/users/{id}

For more clarity, let’s divide the resource archetypes into four categories (document, collection, store and controller) and then you should always target to put a resource into one archetype and then use it’s naming convention consistently. For uniformity’s sake, resist the temptation to design resources that are hybrids of more than one archetype.

  1. document

    A document resource is a singular concept that is akin to an object instance or database record. In REST, you can view it as a single resource inside resource collection. A document’s state representation typically includes both fields with values and links to other related resources.

    Use “singular” name to denote document resource archetype.

    http://api.example.com/device-management/managed-devices/{device-id}
    http://api.example.com/user-management/users/{id}
    http://api.example.com/user-management/users/admin
  2. collection

    A collection resource is a server-managed directory of resources. Clients may propose new resources to be added to a collection. However, it is up to the collection to choose to create a new resource, or not. A collection resource chooses what it wants to contain and also decides the URIs of each contained resource.

    Use “plural” name to denote collection resource archetype.

    http://api.example.com/device-management/managed-devices
    http://api.example.com/user-management/users
    http://api.example.com/user-management/users/{id}/accounts
  3. store

    A store is a client-managed resource repository. A store resource lets an API client put resources in, get them back out, and decide when to delete them. A store never generates new URIs. Instead, each stored resource has a URI that was chosen by a client when it was initially put into the store.

    Use “plural” name to denote store resource archetype.

    http://api.example.com/cart-management/users/{id}/carts
    http://api.example.com/song-management/users/{id}/playlists
  4. controller

    A controller resource models a procedural concept. Controller resources are like executable functions, with parameters and return values; inputs and outputs.

    Use “verb” to denote controller archetype.

    http://api.example.com/cart-management/users/{id}/cart/checkout
    http://api.example.com/song-management/users/{id}/playlist/play

Consistency is the key

Use consistent resource naming conventions and URI formatting for minimum ambiguily and maximum readability and maintainability. You may implement below design hints to achieve consistency:

  1. Use forward slash (/) to indicate a hierarchical relationships

    The forward slash (/) character is used in the path portion of the URI to indicate a hierarchical relationship between resources. e.g.

    http://api.example.com/device-management
    http://api.example.com/device-management/managed-devices
    http://api.example.com/device-management/managed-devices/{id}
    http://api.example.com/device-management/managed-devices/{id}/scripts
    http://api.example.com/device-management/managed-devices/{id}/scripts/{id}
  2. Do not use trailing forward slash (/) in URIs

    As the last character within a URI’s path, a forward slash (/) adds no semantic value and may cause confusion. It’s better to drop them completely.

    http://api.example.com/device-management/managed-devices/
    http://api.example.com/device-management/managed-devices /*This is much better version*/
  3. Use hyphens (-) to improve the readability of URIs

    To make your URIs easy for people to scan and interpret, use the hyphen (-) character to improve the readability of names in long path segments.

    http://api.example.com/inventory-management/managed-entities/{id}/install-script-location  //More readable
    http://api.example.com/inventory-management/managedEntities/{id}/installScriptLocation //Less readable
  4. Do not use underscores ( _ )

    It’s posible to use an underscore in place of hyphen to be used as seperator – But depending on the application’s font, it’s possible that the underscore (_) character can either get partially obscured or completely hidden in some browsers or screens.

    To avoid this confusion, use hyphens (-) instead of underscores ( _ ).

    http://api.example.com/inventory-management/managed-entities/{id}/install-script-location  //More readable
    http://api.example.com/inventory_management/managed_entities/{id}/install_script_location //More error prone
  5. Use lowercase letters in URIs

    When convenient, lowercase letters should be consistently preferred in URI paths.

    RFC 3986 defines URIs as case-sensitive except for the scheme and host components. e.g.

    http://api.example.org/my-folder/my-doc  //1
    HTTP://API.EXAMPLE.ORG/my-folder/my-doc //2
    http://api.example.org/My-Folder/my-doc //3

    In above examples, 1 and 2 are same but 3 is not as it uses My-Folder in capital letters.

  6. Do not use file extenstions

    File extensions look bad and do not add any advantage. Removing them decerase the length of URIs as well. No reason to keep them.

    Apart from above reason, if you want to highlight the media type of API using file extenstion then you should rely on the media type, as communicated through the Content-Type header, to determine how to process the body’s content.

    http://api.example.com/device-management/managed-devices.xml  /*Do not use it*/
    http://api.example.com/device-management/managed-devices /*This is correct URI*/

Never use CRUD function names in URIs

URIs should not be used to indicate that a CRUD function is performed. URIs should be used to uniquely identify resources and not any action upon them. HTTP request methods should be used to indicate which CRUD function is performed.

HTTP GET http://api.example.com/device-management/managed-devices  //Get all devices
HTTP POST http://api.example.com/device-management/managed-devices //Create new Device HTTP GET http://api.example.com/device-management/managed-devices/{id} //Get device for given Id
HTTP PUT http://api.example.com/device-management/managed-devices/{id} //Update device for given Id
HTTP DELETE http://api.example.com/device-management/managed-devices/{id} //Delete device for given Id

Use query component to filter URI collection

Many times, you will come across requirements where you will need a collection of resources sorted, filtered or limited based on some certain resource attribute. For this, do not create new APIs – rather enable sorting, filtering and pagination capabilities in resource collection API and pass the input parameters as query parameters. e.g.

http://api.example.com/device-management/managed-devices
http://api.example.com/device-management/managed-devices?region=USA
http://api.example.com/device-management/managed-devices?region=USA&brand=XYZ
http://api.example.com/device-management/managed-devices?region=USA&brand=XYZ&sort=installation-date

https://spring.io/guides/tutorials/bookmarks/

http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven

I am getting frustrated by the number of people calling any HTTP-based interface a REST API. Today’s example is the SocialSite REST API. That is RPC. It screams RPC. There is so much coupling on display that it should be given an X rating.

What needs to be done to make the REST architectural style clear on the notion that hypertext is a constraint? In other words, if the engine of application state (and hence the API) is not being driven by hypertext, then it cannot be RESTful and cannot be a REST API. Period. Is there some broken manual somewhere that needs to be fixed?

API designers, please note the following rules before calling your creation a REST API:

  • A REST API should not be dependent on any single communication protocol, though its successful mapping to a given protocol may be dependent on the availability of metadata, choice of methods, etc. In general, any protocol element that uses a URI for identification must allow any URI scheme to be used for the sake of that identification. [Failure here implies that identification is not separated from interaction.]
  • A REST API should not contain any changes to the communication protocols aside from filling-out or fixing the details of underspecified bits of standard protocols, such as HTTP’s PATCH method or Link header field. Workarounds for broken implementations (such as those browsers stupid enough to believe that HTML defines HTTP’s method set) should be defined separately, or at least in appendices, with an expectation that the workaround will eventually be obsolete. [Failure here implies that the resource interfaces are object-specific, not generic.]
  • A REST API should spend almost all of its descriptive effort in defining the media type(s) used for representing resources and driving application state, or in defining extended relation names and/or hypertext-enabled mark-up for existing standard media types. Any effort spent describing what methods to use on what URIs of interest should be entirely defined within the scope of the processing rules for a media type (and, in most cases, already defined by existing media types). [Failure here implies that out-of-band information is driving interaction instead of hypertext.]
  • A REST API must not define fixed resource names or hierarchies (an obvious coupling of client and server). Servers must have the freedom to control their own namespace. Instead, allow servers to instruct clients on how to construct appropriate URIs, such as is done in HTML forms and URI templates, by defining those instructions within media types and link relations. [Failure here implies that clients are assuming a resource structure due to out-of band information, such as a domain-specific standard, which is the data-oriented equivalent to RPC’s functional coupling].
  • A REST API should never have “typed” resources that are significant to the client. Specification authors may use resource types for describing server implementation behind the interface, but those types must be irrelevant and invisible to the client. The only types that are significant to a client are the current representation’s media type and standardized relation names. [ditto]
  • A REST API should be entered with no prior knowledge beyond the initial URI (bookmark) and set of standardized media types that are appropriate for the intended audience (i.e., expected to be understood by any client that might use the API). From that point on, all application state transitions must be driven by client selection of server-provided choices that are present in the received representations or implied by the user’s manipulation of those representations. The transitions may be determined (or limited by) the client’s knowledge of media types and resource communication mechanisms, both of which may be improved on-the-fly (e.g., code-on-demand). [Failure here implies that out-of-band information is driving interaction instead of hypertext.]

There are probably other rules that I am forgetting, but the above are the rules related to the hypertext constraint that are most often violated within so-called REST APIs. Please try to adhere to them or choose some other buzzword for your API.

REST – PUT vs POST – REST API Tutorial https://restfulapi.net/rest-put-vs-post/

REST – PUT vs POST

It has been observed that many people struggle to choose between HTTP PUT vs POST methods when designing a system. Though, RFC 2616 has been very clear in differentiating between the two – yet complex wordings are source of confusion for many of us. Lets try to solve the puzzle when to use PUT or POST.

Lets compare them for better understanding.

PUT POST
RFC-2616 clearly mention that PUT method requests for the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource – an update operation will happen, otherwise create operation should happen if Request-URI is a valid resource URI (assuming client is allowed to determine resource identifier).
PUT /questions/{question-id}
The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line. It essentially means that POST request-URI should be of a collection URI.
POST /questions
PUT method is idempotent. So if you send retry a request multiple times, that should be equivalent to single request modification. POST is NOT idempotent. So if you retry the request N times, you will end up having N resources with N different URIs created on server.
Use PUT when you want to modify a singular resource which is already a part of resources collection. PUT replaces the resource in its entirety. Use PATCH if request updates part of the resource. Use POST when you want to add a child resource under resources collection.
PUT is idempotent, so you can cache the response. Responses to this method are not cacheable, unless the response includes appropriate Cache-Control or Expires header fields. However, the 303 (See Other) response can be used to direct the user agent to retrieve a cacheable resource.
Generally, in practice, always use PUT for UPDATE operations. Always use POST for CREATE operations.

PUT vs POST : An Example

Let’s say we are designing a network application. Let’s list down few URIs and their purpose to get better understanding when to use POST and when to use PUT operations.

GET 	/device-management/devices : Get all devices
POST /device-management/devices : Create a new device GET /device-management/devices/{id} : Get the device information identified by "id"
PUT /device-management/devices/{id} : Update the device information identified by "id"
DELETE /device-management/devices/{id} : Delete device by "id"

Follow the similar URI design practices for other resources as well.

Reference: SO Thread

PUT幂等

put update

post create

put  update wholly

patch upate partly

https://help.aliyun.com/document_detail/31947.html

DELETE /?logging HTTP/1.1
Host: BucketName.oss-cn-hangzhou.aliyuncs.com
Date: GMT Date
Authorization: SignatureValue
DELETE /?logging HTTP/1.1
Host: oss-example.oss-cn-hangzhou.aliyuncs.com
Date: Fri, 24 Feb 2012 05:35:24 GMT
Authorization: OSS qn6qrrqxo2oawuk53otfjbyc:6ZVHOehYzxoC1yxRydPQs/Cn****

https://cloud.tencent.com/document/product/436/7749

PUT /<ObjectKey> HTTP/1.1
Host: <BucketName-APPID>.cos.<Region>.myqcloud.com
Date: GMT Date
Content-Type: Content Type
Content-Length: Content Length
Content-MD5: MD5
Authorization: Auth String [Object Content]