<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[Heck's  Blog]]></title> 
<link>https://www.heckjj.com/index.php</link> 
<description><![CDATA[一瞬间的决定，往往可以改变很多，事实上，让自己成功的往往不是知识，是精神！ 如果你总是为自己找借口，那只好让成功推迟。执行力，今天！]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[Heck's  Blog]]></copyright>
<item>
<link>https://www.heckjj.com/post//</link>
<title><![CDATA[Restful API规范]]></title> 
<author>Heck &lt;@hecks.tk&gt;</author>
<category><![CDATA[Web开发]]></category>
<pubDate>Tue, 05 Nov 2024 02:18:56 +0000</pubDate> 
<guid>https://www.heckjj.com/post//</guid> 
<description>
<![CDATA[ 
	一、简介<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RESTful API 是应用程序接口 (API) 的一种架构风格，它使用 HTTP 请求来访问和使用数据。该数据可用于 GET、PUT、POST 和 DELETE 数据类型，这些数据类型是指有关资源的操作的读取、更新、创建和删除。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RESTful API（也称为 RESTful Web 服务或 REST API）基于表示状态传输 (REST)，它是一种架构风格和经常用于 Web 服务开发的通信方法。<br/><br/>二、设计原则。<br/>URL即资源，使用名词表示资源<br/>接口应直观、简洁、风格命名保持一致<br/>必须版本化，具有足够的灵活性来支持上层UI<br/>三、RFC3986标准。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RFC3986标准，简单讲就是规定了如下：除了 数字 + 字母 + -_.~ 不会被转义，其他字符都会被以百分号（%）后跟两位十六进制数 %&#123;hex&#125; 的方式进行转义。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; www 的 post form data 也就是 x-www-form-urlencode 的编码规则：除 -_.（没有 ~） 之外的所有 非字母、非数字 的字符都将被替换成 百分号（%）后跟两位十六进制数 %&#123;hex&#125;，空格（注意）则编码为加号 +。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RFC3986对 ~ 不做转码，x-www-form-urlencode 对 ~ 做转码 %7E。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RFC3986对 空格 转为 %20，x-www-form-urlencode 对 空格 转为 +。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JS的URL编码方式：encodeURIComponent。<br/><br/>// encodeURIComponent<br/>console.log(encodeURIComponent(&quot;hello233 ~-_.&quot;))<br/>hello233%20~-_.<br/><br/>四、URI、URL和URN<br/><br/><a href="https://www.heckjj.com/attachment.php?fid=263" target="_blank"><img src="https://www.heckjj.com/attachment.php?fid=263" class="insertimage" alt="点击在新窗口中浏览此图片" title="点击在新窗口中浏览此图片" border="0"/></a><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; URI（Uniform Resource Identifier ）：统一资源标识符，就是在某一规则下能把一个资源独一无二地标识出来。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;URL（Uniform Resource Locator）：统一资源定位符。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;URN（Uniform Resource Name）：统一资源名称。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;URI可以分为URL,URN或同时具备locators 和names特性的一个东西。URN作用就好像一个人的名字，URL就像一个人的地址。换句话说：URN确定了东西的身份，URL提供了找到它的方式。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;URL是URI的子集, 除了确定一个资源,还提供一种定位该资源的主要访问机制(如其网络“位置”)。例如： http://或 ftp://.。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;当我们替代web地址的时候，URI和URL那个更准确？<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;URI更准确。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;我们经常使用的URI不是严格技术意义上的URL。例如：你需要的文件在files.hp.com. 这是URI，但不是URL--系统可能会对很多协议和端口都做出正确的反应。http://files.hp.com 和ftp://files.hp.com可能得到完全不同的内容。这种情况可能更加普遍，想想不同谷歌域名上的不同服务啊。所以，用URI吧，这样你通常技术上是正确的，URL可不一定。<br/><br/>五、设计规范。<br/>1.版本号<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;应该将API的版本号放入URL。 版本号以字符&#039;v&#039;开头，比如：v1<br/><br/>http://demo.com/cuc/sever/v1<br/> 2.路径(Endpoint)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;接口路径，也称为端点(Endpoint)，代表一种资源的访问地址。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;①使用名词表示资源，使用HTTP Method 描述操作<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;因为&quot;资源&quot;表示一种实体，所以应该是名词，URL不应该有动词，动词应该放在HTTP协议中，CRUD的操作不要体现在URL中。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 反面教材：<br/><br/>查询员工 GET&nbsp;&nbsp;&nbsp;&nbsp; /v1/findEmployee?id=1000&nbsp;&nbsp;<br/>新增员工 POST&nbsp;&nbsp;&nbsp;&nbsp;/v1/addEmployee<br/>更新员工 POST&nbsp;&nbsp;&nbsp;&nbsp;/v1/updateEmployee?id=1000<br/>删除员工 POST&nbsp;&nbsp;&nbsp;&nbsp;/v1/deleteEmployee?id=1000<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 正确实例：<br/><br/>查询员工 GET&nbsp;&nbsp;&nbsp;&nbsp; /v1/employee/1000&nbsp;&nbsp;<br/>新增员工 POST&nbsp;&nbsp;&nbsp;&nbsp;/v1/employee<br/>更新员工 PUT&nbsp;&nbsp;&nbsp;&nbsp; /v1/employee/1000<br/>删除员工 DELETE&nbsp;&nbsp;/v1/employee/1000<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;② 资源既可以是单个，也可以是一个集合，比如：user是单个资源，users是集合资源。 由于英文名词的复数规则众多，为了保持接口命名的一致性，我们建议URL里描述集合资源的名词统一使用单数。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;反面示例：<br/><br/>查询单个员工 GET&nbsp;&nbsp;&nbsp;&nbsp; /v1/employees/1000 <br/>查询一组员工 GET&nbsp;&nbsp;&nbsp;&nbsp; /v1/employees<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;正确示例：<br/><br/>查询单个员工 GET&nbsp;&nbsp;&nbsp;&nbsp; /v1/employee/1000 <br/>查询一组员工 GET&nbsp;&nbsp;&nbsp;&nbsp; /v1/employee<br/>3.使用小写字母，多个单词用&quot;-&quot;分隔，提高URL的可读性<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RFC3986 定义了URI是大小写敏感的(除了scheme和host部分)，为了避免歧义，接口路径应尽量使用小写字母。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;对于由多个单词构成的路径，推荐使用&#039;-&#039;(hyphen)分隔，避免使用驼峰命名（camelCase）、下划线命名(snake_case)、首字母大写的驼峰命名（PascalCase），以提高可读性。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;例子：<br/><br/>camelCase&nbsp;&nbsp;:&nbsp;&nbsp;/v1/customer/1000/shippingAddress&nbsp;&nbsp;[Bad]<br/>snake_case :&nbsp;&nbsp;/v1/customer/1000/shipping_address [Bad]<br/>PascalCase :&nbsp;&nbsp;/v1/customer/1000/ShippingAddress&nbsp;&nbsp;[Bad]<br/> <br/>hyphen&nbsp;&nbsp;&nbsp;&nbsp; :&nbsp;&nbsp;/v1/customer/1000/shipping-address [OK]<br/>4.资源嵌套层次避免过深，尽量不超过2层<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;定义REST接口时，通常使用资源嵌套（多级路径）来标识资源之间的关系，资源嵌套层次尽量不超过2层，否则很难阅读和使用。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;例子：<br/><br/>GET&nbsp;&nbsp;/v1/user/1000/company&nbsp;&nbsp;&nbsp;&nbsp;查询ID等于1000的用户的公司信息<br/>GET&nbsp;&nbsp;/v1/user/1000/company/10 查询ID等于1000的用户所属公司中ID=10的公司信息，嵌套两层<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;反面例子：<br/><br/>GET /v1/company/10/department/20302/employee/10830<br/>GET /v1/zoo/1/area/3/animal/4<br/>六. 筛选(Filtering)、排序(Sorting)、分页(Pagination)、字段选择<br/>&nbsp;&nbsp;1.筛选（Filtering)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;接口URL尽量保持简短，对于集合资源不同纬度的筛选，可通过组合不同的Query Param来实现。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;反面案例：<br/><br/>GET /v1/externalEmployees<br/>GET /v1/internalEmployees<br/>GET /v1/internalAndSeniorEmployees<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;正确案例：<br/><br/>GET /v1/employee?state=internal&amp;title=senior<br/>2.排序(Sorting)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;单个字段排序：<br/><br/>GET /v1/employee?sort=age&amp;order=asc<br/>GET /v1/employee?sort=age&amp;order=desc<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;多个字段排序：<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;字段名前缀,&#039;+&#039;：表示升序，&#039;-&#039;：降序，多个字段名以逗号分隔<br/><br/>GET /v1/employee?sort=+age,-userName<br/>3.分页(Pagination)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;对于数据量比较大的集合资源，接口实现一定要支持分页。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;常规分页有两个重要的参数：&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/><br/>pageNo 获取那一页的记录，默认第一页。<br/>pageSize 每页返回多少条数据，推荐默认值25，必须限定此参数的最大值。<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;返回的资源列表为：[(pageNo-1)pageSize, pageNopageSize)<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;请求示例：<br/><br/>GET /v1/employee?pageNo=8&amp;pageSize=20&amp;sort=age&amp;order=desc<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;返回值可以采用以下数据格式：<br/><br/>&#123;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&quot;pageSize&quot;:20,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 页尺寸<br/>&nbsp;&nbsp;&nbsp;&nbsp;&quot;pageNo&quot;:8,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 页码<br/>&nbsp;&nbsp;&nbsp;&nbsp;&quot;totalCount&quot;:182,&nbsp;&nbsp;// 总记录数<br/>&nbsp;&nbsp;&nbsp;&nbsp;&quot;pageList&quot;:[<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;id&quot;:13483,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;name&quot;:&quot;Hehe&quot;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;title&quot;:&quot;senior&quot;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;id&quot;:13484,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;name&quot;:&quot;haha&quot;,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;title&quot;:&quot;junior&quot;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;]<br/>&#125;<br/><br/>4.字段选择<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;调用方可能只需要资源的少量属性，接口提供方可支持客户端通过请求参数fields来选择返回的字段，多个字段以逗号分隔，示例如下：<br/><br/>GET /v1/employee?fields=id,name,age&amp;pageNo=1&amp;pageSize=20&amp;sort=age&amp;order=desc
]]>
</description>
</item><item>
<link>https://www.heckjj.com/post//#blogcomment</link>
<title><![CDATA[[评论] Restful API规范]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>https://www.heckjj.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>