<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title>REST - 标签 - 菠菜眾長</title><link>https://lruihao.cn/tags/rest/</link><description>REST - 标签 - 菠菜眾長</description><generator>Hugo -- gohugo.io</generator><language>zh-CN</language><managingEditor>1024@lruihao.cn (Lruihao)</managingEditor><webMaster>1024@lruihao.cn (Lruihao)</webMaster><lastBuildDate>Thu, 14 Nov 2019 19:06:05 +0000</lastBuildDate><atom:link href="https://lruihao.cn/tags/rest/" rel="self" type="application/rss+xml"/><item><title>RESTful</title><link>https://lruihao.cn/posts/restful/</link><pubDate>Thu, 14 Nov 2019 19:06:05 +0000</pubDate><author>Lruihao</author><guid>https://lruihao.cn/posts/restful/</guid><description><![CDATA[<blockquote>
<p>RESTful 是一种系统开发设计风格、原则。可视情况调整，以下参考来源 <a href="https://www.rfc-editor.org/rfc/rfc5789"target="_blank" rel="external nofollow noopener noreferrer">RFC5789<i class="fa-solid fa-external-link-alt fa-fw fa-xs ms-1 text-secondary" aria-hidden="true"></i></a></p>
</blockquote>
<h2 id="noun">Noun</h2>
<ul>
<li>一般资源
通用于一律使用复数名词
例如：/books 或 /books/123。但有部分人认为应该使用单数名词，因为： /book/123 看似比 /books/123 合理。但想想文件系统的目录命名（例如 /Users 或 /Documents)，其实用复数也没问题。复数可以保持 API endpoint 的一致性，所以一般资源建议用复数。</li>
<li>唯一资源：对 client 而言只有一份的资源
通用于单数名词
例如：user 是指目前验证的使用者，使用者永远只能同时登入一个使用者</li>
</ul>
<h2 id="http-method">Http Method</h2>
<table><tbody><tr><th>Method</th><th>Idempotent</th><th>Safe</th><th>CRUD</th><th>OO</th><th>生活动词</th><th>用途</th></tr><tr><td rowspan="2">GET</td><td rowspan="2" style="text-align: center;">Y</td><td rowspan="2" style="text-align: center;">Y</td><td rowspan="2"><b>R</b>ead</td><td rowspan="2">get</td><td>get</td><td>取得资料</td></tr><tr><td>list</td><td>列出资料</td></tr><tr><td rowspan="2">POST</td><td rowspan="2"></td><td rowspan="2"></td><td rowspan="2"><b>C</b>reate</td><td rowspan="2">add</td><td>create</td><td>建立一个可以完全独立存在的实体</td></tr><tr><td>add</td><td>增加一个必须依赖于某个实体的实体</td></tr><tr><td rowspan="2">PUT</td><td rowspan="2" style="text-align: center;">Y</td><td rowspan="2"></td><td rowspan="3"><b>U</b>pdate</td><td rowspan="3">set</td><td>replace</td><td>取代一个关系，已存在时先删除后建立，不存在时直接建立</td></tr><tr><td>add</td><td>附加唯一关系，两个关系实体可以互相独立存在，且已经存在</td></tr><tr><td>PATCH</td><td></td><td></td><td>edit</td><td>编辑某个实体</td></tr><tr><td>DELETE</td><td></td><td></td><td><b>D</b>elete</td><td>remove</td><td>remove<br>delete</td><td>删除某个实体</td></tr></tbody></table>
<ul>
<li>Safe：该操作不会改变伺服器端的资源状态（而且结果可以被 cache），属于 Safe 的操作必定属于 Idempotent</li>
<li>Idempotent (幂等性)：该操作不管做 1 遍或做 n 遍，都会得到同样的资源状态结果（但不一定得到同样的返回值，例如第 2 次 DELETE 请求可能回传 404），因此 client 端可以放心 retry</li>
</ul>
<h3 id="get">GET</h3>
<blockquote>
<p>Safe：每次执行操作时，GET 只有读取 Resource，不会改变到任何的 Resource （资源，资料）<br>
Idempotent：每次执行操作时，GET 只有读取 Resource，不会改变到任何的 Resource （资源，资料），所以任何资源的任何状态都是一样的</p>
</blockquote>
<h3 id="post">POST</h3>
<blockquote>
<p>每次执行操作时，POST 都会建立一个 Resource （资源，资料）</p>
</blockquote>
<ul>
<li>
<p>Create：建立一个可以完全独立存在的实体</p>
<p>范例：建立使用者</p>
<p>执行第一次时：建立一个 name = &ldquo;李四&rdquo; 的 user，但其 id = 1，执行第二次时：建立一个 name = &ldquo;李四&rdquo; 的 user，但其 id = 2，发送同样的请求，可每次都是不同的 Resource</p>
<p>建立使用者前不需要建立任何的东西，就可以建立使用者了，使用者是可以完全独立的存在</p>
<div class="highlight" id="id-1"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-http" data-lang="http"><span class="line"><span class="cl"><span class="nf">POST</span> <span class="nn">/users</span> <span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span>
</span></span><span class="line"><span class="cl"><span class="n">Host</span><span class="o">:</span> <span class="l">127.0.0.1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="g">{
</span></span></span><span class="line"><span class="cl"><span class="g"> &#34;name&#34;: &#34;李四&#34;
</span></span></span><span class="line"><span class="cl"><span class="g">}</span></span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>Add：增加一个必须依赖于某个实体的实体</p>
<p>资料结构：一对多的关系</p>
<p>范例：Add a public key on behalf of a user 增加一个代表使用者的公钥 (<a href="https://gitea.com/api/swagger#/admin/adminCreatePublicKey"target="_blank" rel="external nofollow noopener noreferrer">Gitea API<i class="fa-solid fa-external-link-alt fa-fw fa-xs ms-1 text-secondary" aria-hidden="true"></i></a>)</p>
<p>增加这个公钥之前，使用者必须存在，公钥必须归属于某个使用者之下，公钥跟姓名一样，使用相同电脑的公钥就会相同，但不表示是同一个使用者，故公钥也会有自己的 ID 我每次增加公钥时，都将生成不同的公钥 ID</p>
<div class="highlight" id="id-2"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-http" data-lang="http"><span class="line"><span class="cl"><span class="nf">POST</span> <span class="nn">/api/v1/admin/users/{username}/keys</span> <span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span>
</span></span><span class="line"><span class="cl"><span class="n">Host</span><span class="o">:</span> <span class="l">gitea.com</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="g">{
</span></span></span><span class="line"><span class="cl"><span class="g">  &#34;key&#34;: &#34;string&#34;,
</span></span></span><span class="line"><span class="cl"><span class="g">  &#34;read_only&#34;: true,
</span></span></span><span class="line"><span class="cl"><span class="g">  &#34;title&#34;: &#34;string&#34;
</span></span></span><span class="line"><span class="cl"><span class="g">}</span></span></span></code></pre></td></tr></table>
</div>
</div></li>
</ul>
<h3 id="put">PUT</h3>
<blockquote>
<p>Idempotent：每次执行操作时，PUT 都会取代 Resource，不管操作几次，使用者获取得 Resource 结果都是一样的</p>
<p>Replace：不论资源如何，最终的资源状态都是一样的，Resource 已存在时，或许不理会、或许先删除后建立（取代）Resource 不存在时，直接建立</p>
<p>Add：添加唯一关系，建立这个唯一关系前，两个关连实体都必须存在。在没有建立关系前，两个关连实体都可以互相独立存在
资料结构：多对多，且两个关连实体的 PK，同时也是关系实体的 PK、FK</p>
</blockquote>
<ul>
<li>
<p>范例：增加使用者与角色的关系</p>
<p>增加使用者跟角色的关系前，使用者跟角色都必须存在；增加使用者跟角色的关系前，使用者跟角色可以独立存在，
使用者 12262 跟 角色 2 的关系最多只能有一条关系（ 使用者 12262 有 角色 2)，最少没有关系（使用者 12262 没有 角色 2 ) ，执行第二次操作时，使用者 12262 跟 角色 2 的从属关系仍然存在，也不会跑出第二条 使用者 12262 跟 角色 2 的从属关系</p>
<div class="highlight" id="id-3"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-http" data-lang="http"><span class="line"><span class="cl"><span class="nf">PUT</span> <span class="nn">user/{account}/roles</span> <span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span>
</span></span><span class="line"><span class="cl"><span class="n">Host</span><span class="o">:</span> <span class="l">127.0.0.1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="g">{
</span></span></span><span class="line"><span class="cl"><span class="g">  &#34;role_id&#34;: &#34;2&#34;
</span></span></span><span class="line"><span class="cl"><span class="g">}</span></span></span></code></pre></td></tr></table>
</div>
</div></li>
<li>
<p>范例：Follow a user 关注一个使用者 (<a href="https://gitea.com/api/swagger#/user/userCurrentPutFollow"target="_blank" rel="external nofollow noopener noreferrer">Gitea API<i class="fa-solid fa-external-link-alt fa-fw fa-xs ms-1 text-secondary" aria-hidden="true"></i></a>)</p>
<p>增加关注关系时，关注者与被关注者（都是使用者） 都必须存在；关注者 12262 跟被关注者 12231 的关系最多只能有一条关系（12262 关注 12231），最少没有关系（12262 不关注 12231），执行第二次操作时，关注者 12262 跟被关注者 12231 的关注关系仍然存在，也不会跑出第二条关注者 12262 跟被关注者 12231 的关注关系</p>
<div class="highlight" id="id-4"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-http" data-lang="http"><span class="line"><span class="cl"><span class="nf">PUT</span> <span class="nn">/api/v1/user/following/{username}</span> <span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span>
</span></span><span class="line"><span class="cl"><span class="n">Host</span><span class="o">:</span> <span class="l">gitea.com</span></span></span></code></pre></td></tr></table>
</div>
</div></li>
</ul>
<h3 id="patch">PATCH</h3>
<blockquote>
<p>Edit：编辑可独立存在、且已经存在的实体，也就是产生新版本的实体，可能会影响其他 Resource</p>
</blockquote>
<ul>
<li>
<p>范例：编辑使用者</p>
<p>编辑使用者，使用者已经存在，且我们可能有纪录编辑时间、编辑人、编辑 IP，所以每次的编辑都会造成不一样的结果
第一次编辑使用者，更新时间变为 08:00，编辑人 12262，IP 172.18.0.66 第二次编辑使用者，更新时间变为 09:00，编辑人 12263，IP 172.18.0.67</p>
<div class="highlight" id="id-5"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-http" data-lang="http"><span class="line"><span class="cl"><span class="nf">PATCH</span> <span class="nn">/users/{account}</span> <span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span>
</span></span><span class="line"><span class="cl"><span class="n">Host</span><span class="o">:</span> <span class="l">127.0.0.1</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="g">{
</span></span></span><span class="line"><span class="cl"><span class="g">	&#34;username&#34;: &#34;李四&#34;,
</span></span></span><span class="line"><span class="cl"><span class="g">	&#34;age&#34;: &#34;18&#34;,
</span></span></span><span class="line"><span class="cl"><span class="g">	&#34;gender&#34;: &#34;male&#34;
</span></span></span><span class="line"><span class="cl"><span class="g">}</span></span></span></code></pre></td></tr></table>
</div>
</div></li>
</ul>
<h3 id="delete">DELETE</h3>
<blockquote>
<p>Idempotent：每次执行操作时，DELETE 都会删除相同的东西</p>
</blockquote>
<ul>
<li>
<p>范例：删除使用者</p>
<p>第一次删除使用者 12262，删除使用者 12262, 第二次删除使用者 12262，还是删除使用者 12262，只不过使用者 12262 不存在了</p>
<div class="highlight" id="id-6"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-http" data-lang="http"><span class="line"><span class="cl"><span class="nf">DELETE</span> <span class="nn">/users/{account}</span> <span class="kr">HTTP</span><span class="o">/</span><span class="m">1.1</span>
</span></span><span class="line"><span class="cl"><span class="n">Host</span><span class="o">:</span> <span class="l">127.0.0.1</span></span></span></code></pre></td></tr></table>
</div>
</div></li>
</ul>
<h2 id="http-status-code">HTTP Status Code</h2>
<p>HTTP 状态码（HTTP Status Code）是用以表示网页服务器 HTTP 响应状态的 3 位数字代码。所有状态码的第一个数字代表了响应的五种状态之一。除非另有说明，状态码是 <strong>HTTP/1.1 标准</strong>（<a href="https://www.rfc-editor.org/rfc/rfc7231"target="_blank" rel="external nofollow noopener noreferrer">RFC 7231<i class="fa-solid fa-external-link-alt fa-fw fa-xs ms-1 text-secondary" aria-hidden="true"></i></a>）的一部分。</p>
<p>而关于 RESTful API 的请求状态，通常有以下两种设计方案：</p>
<ul>
<li>方案一：使用 HTTP 状态码来表示请求状态，200 时返回的内容就是数据</li>
<li>方案二：所有接口都返回 200 ，在响应内容里约定错误码或错误信息</li>
</ul>
<p>在实际应用中，应据具体情景及需要进行选择与调整。</p>
<table><tbody><tr><th>方案</th><th colspan="2">优劣比较</th></tr><tr><td rowspan="2">方案一</td><td>优点</td><td>对服务端来说较为简单方便</td></tr><tr><td>缺点</td><td>客户端难以根据状态码处理复杂问题</td></tr><tr><td rowspan="2">方案二</td><td>优点</td><td>方便对返回资料进行统一处理和细微性的控制</td></tr><tr><td>缺点</td><td>相当于放弃了 HTTP 状态码的语义</td></tr></tbody></table>
<h3 id="常用-http-状态码">常用 HTTP 状态码</h3>
<table>
<thead>
<tr>
<th>Code</th>
<th>Message</th>
<th>用途</th>
</tr>
</thead>
<tbody>
<tr>
<td>1XX</td>
<td>Informational response</td>
<td>此类状态码通常代表的响应都是信息性的，告诉客户端可以进行下一步操作。</td>
</tr>
<tr>
<td>100</td>
<td>Continue</td>
<td>表示服务端已接收到请求头，客户端可以继续发送请求体（如 POST 请求）。</td>
</tr>
<tr>
<td>101</td>
<td>Switching Protocols</td>
<td>表示服务端支持更优协议，让客户端在服务端更换协议后重新访问。</td>
</tr>
<tr>
<td>2XX</td>
<td>Successful</td>
<td>此类状态码通常代表请求已成功被服务端接收、理解并接受。</td>
</tr>
<tr>
<td>200</td>
<td>OK</td>
<td>表示请求成功。</td>
</tr>
<tr>
<td>201</td>
<td>Created</td>
<td>表示请求已被实现，通常是在成功创建了某个资源。</td>
</tr>
<tr>
<td>202</td>
<td>Accepted</td>
<td>表示请求已被服务端接收，但尚未进行处理。</td>
</tr>
<tr>
<td>204</td>
<td>No Content</td>
<td>表示请求成功，但不会返回任何内容。</td>
</tr>
<tr>
<td>205</td>
<td>Reset Content</td>
<td>表示请求成功，但不会返回任何内容，并且要求客户端重置表单。</td>
</tr>
<tr>
<td>3XX</td>
<td>Redirect</td>
<td>此类状态码通常代表本次请求需要客户端采取进一步操作才能完成。通常用于重定向。</td>
</tr>
<tr>
<td>300</td>
<td>Multiple Choices</td>
<td>表示请求的资源有多个供可选择，客户端可自行选择一个进行请求的重定向。</td>
</tr>
<tr>
<td>301</td>
<td>Moved Permanently</td>
<td>表示请求的资源已经永久地移动到了新位置，并且将在 Location 域中携带该资源新的 URI。</td>
</tr>
<tr>
<td>304</td>
<td>Not Modified</td>
<td>表示请求的资源无发生修改，将不会返回任何资源。</td>
</tr>
<tr>
<td>4XX</td>
<td>Client Error</td>
<td>此类状态码通常代表客户端可能出现了错误。</td>
</tr>
<tr>
<td>400</td>
<td>Bad Request</td>
<td>表示客户端发出的请求有误（格式、大小、无效的&hellip;)，服务端不能/ 不会处理该请求。</td>
</tr>
<tr>
<td>401</td>
<td>Unauthorized</td>
<td>表示客户端未能提供必要的验证，服务端拒绝提供资源。</td>
</tr>
<tr>
<td>403</td>
<td>Forbidden</td>
<td>表示服务端理解了该请求，但客户端没有足够权限以访问，遂拒绝提供该资源。</td>
</tr>
<tr>
<td>404</td>
<td>Not Found</td>
<td>表示服务端无法找到请求的资源，其可能已经暂时（永久）失效。</td>
</tr>
<tr>
<td>408</td>
<td>Request Timeout</td>
<td>表示请求超时。</td>
</tr>
<tr>
<td>409</td>
<td>Conflict</td>
<td>表示请求的资源发送了冲突，通常是 PUT 请求。</td>
</tr>
<tr>
<td>410</td>
<td>Gone</td>
<td>表示请求的资源已经永久失效，客户端不应再次请求。</td>
</tr>
<tr>
<td>411</td>
<td>Length Required</td>
<td>表示服务端拒绝在没有定义 Content-Length 头的情况下接收该请求。</td>
</tr>
<tr>
<td>5XX</td>
<td>Server Error</td>
<td>此类状态码通常代表由于服务端的原因，导致无法完成请求。</td>
</tr>
<tr>
<td>500</td>
<td>Internal Server Error</td>
<td>表示由于服务端遇到意料之外的变故，导致无法完成请求。</td>
</tr>
<tr>
<td>501</td>
<td>Not Implemented</td>
<td>表示服务端不支持完成请求所需的功能，导致无法完成请求。</td>
</tr>
<tr>
<td>502</td>
<td>Bad Gateway</td>
<td>表示作为网关或代理的服务段在执行请求时，从上游服务器获得了无效的响应。</td>
</tr>
<tr>
<td>503</td>
<td>Service Unavailable</td>
<td>表示由于某些原因（服务器超载或系统维护等），导致暂时无法完成请求。</td>
</tr>
<tr>
<td>504</td>
<td>Gatewy Timeout</td>
<td>表示作为网关或代理的服务段在执行请求时，未能及时从上游服务器获得响应。</td>
</tr>
<tr>
<td>505</td>
<td>HTTP Version Not Supported</td>
<td>表示服务端不支持请求的 HTTP 协议版本，导致无法完成请求。</td>
</tr>
</tbody>
</table>
<blockquote>
<p>以上内容参考自<a href="https://zh.wikipedia.org/zh-cn/HTTP%e7%8a%b6%e6%80%81%e7%a0%81"target="_blank" rel="external nofollow noopener noreferrer">https://zh.wikipedia.org/zh-cn/HTTP状态码<i class="fa-solid fa-external-link-alt fa-fw fa-xs ms-1 text-secondary" aria-hidden="true"></i></a>，
需要查看完整 HTTP 状态码请点击 <a href="https://www.rfc-editor.org/rfc/rfc9110.html#name-status-codes"target="_blank" rel="external nofollow noopener noreferrer">https://www.rfc-editor.org/rfc/rfc9110.html#name-status-codes<i class="fa-solid fa-external-link-alt fa-fw fa-xs ms-1 text-secondary" aria-hidden="true"></i></a></p>
</blockquote>]]></description></item><item><title>Web 开发规则，代码规范</title><link>https://lruihao.cn/posts/dev-rules/</link><pubDate>Thu, 15 Aug 2019 18:30:31 +0000</pubDate><author>Lruihao</author><guid>https://lruihao.cn/posts/dev-rules/</guid><description><![CDATA[<h2 id="精神">精神</h2>
<ul>
<li>绝不写死代码，硬编码</li>
<li>不留不要用的、垃圾代码</li>
</ul>
<h2 id="git">Git</h2>
<ul>
<li>Master 的 BUG 必须最少且趋近于零，为最稳定的版本</li>
<li>每次 Commit 信息应该准确填写。不可模棱两可，eg: 修复 BUG、增加功能</li>
<li>禁止 Commit IDE 的 project data，e.g: .vscode</li>
<li>禁止上传垃圾代码</li>
</ul>
<blockquote>
<p>更多规则详见文档 <a href="/posts/commit-spec/">Commit 规范</a></p>
</blockquote>
<h3 id="分支branch">分支（Branch）</h3>
<ul>
<li>命名规则：应以此分支主要目的命名（修复什么 BUG，新增特定功能）</li>
<li>合并后的分支应该删除</li>
</ul>
<h3 id="commit">commit</h3>
<ul>
<li>遵循一个功能一个 commit 的原则</li>
</ul>
<h2 id="restful">Restful</h2>
<ul>
<li>
<p>资源名词站在 API 的角度思考</p>
<ul>
<li>
<p>复数名词：可以复数笔数据，回传结果为 Array</p>
<p>举例：GET/users 取得多笔使用者资料</p>
<ul>
<li>刪除，放在复数名词內，让 Router 保持一致性</li>
<li>增加，放在复数名詞內，让 Router 保持一致性</li>
</ul>
</li>
<li>
<p>单数名词：仅取得单笔数据，必须指定 PK，两两一组，回传结果为 Object
举例：GET/user/{accont} 取得单笔使用者资料，必须指定 PK</p>
</li>
</ul>
</li>
<li>
<p>URL 中一律不带 id 参数</p>
</li>
</ul>
<div class="highlight" id="id-1"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">正确范例： calendar_manager/calendar/29
</span></span><span class="line"><span class="cl">错误范例： calendar_manager/calendar/29?id=29</span></span></code></pre></td></tr></table>
</div>
</div><blockquote>
<p>更多规则详见文档 <a href="/posts/restful/">RESTful</a></p>
</blockquote>
<h2 id="命名">命名</h2>
<ul>
<li>命名应根据内容做有意义的命名，让后续维护人员可以顾名思义！</li>
<li>即使不会发生错误，代码英文大小写也需明确区分。</li>
</ul>
<h3 id="语意">语意</h3>
<table>
<thead>
<tr>
<th style="text-align:left">类型</th>
<th style="text-align:left">命名规则</th>
<th style="text-align:left">说明</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">属性 (Attribute, Property)</td>
<td style="text-align:left">名词 user_name、userName</td>
<td style="text-align:left"></td>
</tr>
<tr>
<td style="text-align:left">方法 (Method, Function)</td>
<td style="text-align:left">动词 + 名词 getUserName、get_user_name</td>
<td style="text-align:left">常見的动词有：get、set、update、delete、remove</td>
</tr>
</tbody>
</table>
<h3 id="字母与分隔">字母与分隔</h3>
<table>
<thead>
<tr>
<th>语言</th>
<th>变量 (Variable, Parameter, Argument)</th>
<th>常量 (Constant)</th>
<th>面向对象 - 类名 (Class Name)</th>
<th>面向对象 - 成员 (mebmer)</th>
</tr>
</thead>
<tbody>
<tr>
<td>HTML</td>
<td>全部小写，不同单词以「-」分隔<br />e.g: user-id</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>CSS、SCSS</td>
<td>全部小写，不同单词以「-」分隔，CSS 变量以「&ndash;」开头，SCSS 变量以「$」开头<br />e.g: .user-id、&ndash;header-height、$header-height</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>JavaScript</td>
<td>驼峰式命名法<br />首字小写，不同单字「首字以大写」分隔<br /> e.g: userId</td>
<td>全部大写，不同单字以「_」分隔 MAX_COUNT</td>
<td>驼峰式命名法<br />首字大写，不同单字「首字以大写」分隔<br />一个文件放一个 Class, 文件名即为 Class Name <br />e.g: User</td>
<td>驼峰式命名法<br />公有 (public) : 首字小写，不同单词「首字以大写」分隔<br />e.g: name, getName<br />私有 (private): _公有命名规则<br />e.g: _name,_getName</td>
</tr>
<tr>
<td>Vue</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Java</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>PHP</td>
<td>全部小写，不同单词以「_」分隔<br />e.g: user_id</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>Python</td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>SQL</td>
<td>由使用者定义的：表名、字段名<br />全部小写，不同单词以「_」分隔</td>
<td>SQL 语法、函数全部大写<br />e.g: SELECT、INSERT INTO</td>
<td></td>
<td></td>
</tr>
</tbody>
</table>
<h2 id="通用">通用</h2>
<ul>
<li>代码编写</li>
<li><strong>每个函数应该使用块注释，注释应包含函数功能说明、参数说明</strong>。规则见：JSDoc、JavaDoc</li>
<li>不必要的代码不要写，也应禁止放到注释里面！</li>
<li>if-else 的 {} 严禁省略</li>
<li>
</li>
<li>代码规范、代码排版等可通过 eslint 等工具做统一处理</li>
</ul>
<h3 id="正确写法">正确写法</h3>
<div class="highlight" id="id-2"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">public</span> <span class="kd">function</span> <span class="nx">test</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// do something
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="k">if</span> <span class="p">(</span><span class="nx">a</span> <span class="o">===</span> <span class="nx">b</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// do something
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></td></tr></table>
</div>
</div><h2 id="错误写法">错误写法</h2>
<div class="highlight" id="id-3"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">public</span> <span class="kd">function</span> <span class="nx">test</span> <span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// do something
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="k">if</span> <span class="p">(</span><span class="nx">a</span> <span class="o">===</span> <span class="nx">b</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// do something
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>代码排版
<ul>
<li>任何代码应该以 2 个 space 为一个缩进做好排版、不可使用 tab</li>
</ul>
</li>
<li>函数 (Function, Methd)
<ul>
<li>函数声明时需在函数上方加上函数注释，注释应包含函数说明、参数内容（参数类型、参数英文名称、参数说明）、返回值内容（返回值类型、返回值说明）</li>
</ul>
</li>
<li>类 (Class)
<ul>
<li>一个类（Class）的声明只能存在一个文件</li>
<li>类（Class）的声明文件，文件名必须为类名</li>
</ul>
</li>
<li>其他
<ul>
<li>连接本地任何其他资源（图片、文件、网站）皆使用相对路径，禁止使用绝对路径，非本地资源除外</li>
</ul>
</li>
</ul>
<h2 id="html">HTML</h2>
<h3 id="代码编写">代码编写</h3>
<ul>
<li>禁止在 HTML 使用 <code>&lt;style&gt;</code>、<code>&lt;script&gt;</code>，一律使用外部档案引用方式引用 CSS、JavaScript 文件</li>
<li>HTML 标签需成双成对，有头有尾</li>
<li>块级标签：<code>&lt;tag&gt;&lt;/tag&gt;</code></li>
<li>单标签：<code>&lt;tag /&gt;</code></li>
<li>禁止使用已被 HTML 舍弃的旧标签、属性，如：</li>
</ul>
<div class="highlight" id="id-4"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="c">&lt;!-- html tag --&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">center</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">font</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">basefont</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">s</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">strike</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">u</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">listing</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">plaintext</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">xmp</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="c">&lt;!-- html attribute --&gt;</span>
</span></span><span class="line"><span class="cl">align
</span></span><span class="line"><span class="cl">bgcolor
</span></span><span class="line"><span class="cl">color</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="css">CSS</h2>
<blockquote>
<p>CSS 的定义应该独立一个 CSS 文件，禁止使用 <code>&lt;style&gt;</code> 或 <code>style</code> 属性直接在 HTML 中定义样式。</p>
</blockquote>
<h2 id="javascript">JavaScript</h2>
<blockquote>
<p>禁止使用 HTML 字串，一律使用 Dom 产生 HTML, e.g: <code>document.createDocumentFragment()</code></p>
</blockquote>
<h3 id="注释">注释</h3>
<p>JavaScript 注释应该遵循 JSDoc 的标准撰写</p>
<h4 id="全局变量-global">全局变量 (Global)</h4>
<div class="highlight" id="id-5"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="cm">/* global ZT */</span></span></span></code></pre></td></tr></table>
</div>
</div><h4 id="常量-constant">常量 (Constant)</h4>
<div class="highlight" id="id-6"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="cm">/**
</span></span></span><span class="line"><span class="cl"><span class="cm"> * 常量說明
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @type {常量类型}
</span></span></span><span class="line"><span class="cl"><span class="cm"> */</span></span></span></code></pre></td></tr></table>
</div>
</div><p><strong>Example</strong></p>
<div class="highlight" id="id-7"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="cm">/**
</span></span></span><span class="line"><span class="cl"><span class="cm"> * 请求地址
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @type {String}
</span></span></span><span class="line"><span class="cl"><span class="cm"> */</span>
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">REQUEST_URL</span> <span class="o">=</span> <span class="s1">&#39;http://localhost:8080&#39;</span><span class="p">;</span></span></span></code></pre></td></tr></table>
</div>
</div><h4 id="函數方法-function-method">函數、方法 (Function, Method)</h4>
<div class="highlight" id="id-8"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="cm">/**
</span></span></span><span class="line"><span class="cl"><span class="cm"> * 函数用途说明
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @param {参数类型} 参数名称参数说明
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @param {参数类型} [选择性参数名称] 参数说明
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @param {参数类型} [选择性参数名称=参数预设值] 参数说明
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @returns {返回值类型} 返回值说明
</span></span></span><span class="line"><span class="cl"><span class="cm"> */</span></span></span></code></pre></td></tr></table>
</div>
</div><p><strong>Example</strong></p>
<div class="highlight" id="id-9"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="cm">/**
</span></span></span><span class="line"><span class="cl"><span class="cm"> * 取得使用者
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @param {Int} userId 使用者 ID
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @param {Object} [options] 其他选项
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @param {String} [options.query=&#39;a&#39;] 查询关键词 默认为 &#39;a&#39;
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @returns {Object} 使用者资料
</span></span></span><span class="line"><span class="cl"><span class="cm"> */</span>
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">getUser</span><span class="p">(</span><span class="nx">userId</span><span class="p">,</span> <span class="nx">options</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// do something
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="k">return</span> <span class="nx">user</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></td></tr></table>
</div>
</div><h2 id="vue">Vue</h2>
<ul>
<li><i class="fa-regular fa-square fa-fw" aria-hidden="true"></i> 待补充</li>
</ul>
<h2 id="java">Java</h2>
<p>Java 注释应该遵循 JavaDoc 的标准撰写</p>
<ul>
<li><i class="fa-regular fa-square fa-fw" aria-hidden="true"></i> 待补充</li>
</ul>
<h2 id="php">PHP</h2>
<h3 id="前端参数取得">前端参数取得</h3>
<p>参数取得需通过 filter_input 函数取得，不得使用 _GET 、_POST</p>
<h3 id="输出到前台">输出到前台</h3>
<p>参数命名必须为：全部小写，不同单字以「_」分隔</p>
<h3 id="注解">注解</h3>
<p>PHP 注解应该遵循 PHPDoc 的标准撰写</p>
<h3 id="成员变量-member">成员变量 (Member)</h3>
<p>成员变量只的是 Class 内的成员变数，我们都会要求替成员变量增加注解说明。通常 Function 的变量除非太特别否则都不需要特别注解说明。</p>
<div class="highlight" id="id-10"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-php" data-lang="php"><span class="line"><span class="cl"><span class="sd">/**
</span></span></span><span class="line"><span class="cl"><span class="sd"> * 成员变量說明
</span></span></span><span class="line"><span class="cl"><span class="sd"> * @type {类型}
</span></span></span><span class="line"><span class="cl"><span class="sd"> */</span></span></span></code></pre></td></tr></table>
</div>
</div><p><strong>Example</strong></p>
<div class="highlight" id="id-11"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-php" data-lang="php"><span class="line"><span class="cl"><span class="sd">/**
</span></span></span><span class="line"><span class="cl"><span class="sd"> * 使用者 ID
</span></span></span><span class="line"><span class="cl"><span class="sd"> * @type {String}
</span></span></span><span class="line"><span class="cl"><span class="sd"> */</span>
</span></span><span class="line"><span class="cl"><span class="nv">$userId</span> <span class="o">=</span> <span class="s1">&#39;Hello&#39;</span><span class="p">;</span></span></span></code></pre></td></tr></table>
</div>
</div><h3 id="函数方法-function-method">函数、方法 (Function, Method)</h3>
<div class="highlight" id="id-12"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-php" data-lang="php"><span class="line"><span class="cl"><span class="sd">/**
</span></span></span><span class="line"><span class="cl"><span class="sd"> * 函数用途说明
</span></span></span><span class="line"><span class="cl"><span class="sd"> * @param 参数型态 参数名称 参数说明
</span></span></span><span class="line"><span class="cl"><span class="sd"> * @option 参数选项类型 参数选项名称 参数选项说明
</span></span></span><span class="line"><span class="cl"><span class="sd"> * @uses 全局变量 全域变数说明
</span></span></span><span class="line"><span class="cl"><span class="sd"> * @returns 返回值类型 返回值说明
</span></span></span><span class="line"><span class="cl"><span class="sd"> */</span></span></span></code></pre></td></tr></table>
</div>
</div><p><strong>Example</strong></p>
<div class="highlight" id="id-13"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-php" data-lang="php"><span class="line"><span class="cl"><span class="sd">/**
</span></span></span><span class="line"><span class="cl"><span class="sd"> * 取得使用者
</span></span></span><span class="line"><span class="cl"><span class="sd"> * @param int userId 使用者 ID
</span></span></span><span class="line"><span class="cl"><span class="sd"> * @param object options 其他选项
</span></span></span><span class="line"><span class="cl"><span class="sd"> * @option string options[&#39;query&#39;] 查询关键字
</span></span></span><span class="line"><span class="cl"><span class="sd"> * @uses $_POST[&#39;role_id&#39;] 从前端以 POST 取得角色 ID
</span></span></span><span class="line"><span class="cl"><span class="sd"> * @returns object 使用者资料
</span></span></span><span class="line"><span class="cl"><span class="sd"> */</span>
</span></span><span class="line"><span class="cl"><span class="k">function</span> <span class="nf">getUser</span> <span class="p">(</span><span class="nv">$userId</span><span class="p">,</span> <span class="nv">$options</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="c1">// do something
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>  <span class="k">return</span> <span class="nv">$user</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span></span></span></code></pre></td></tr></table>
</div>
</div><h2 id="python">Python</h2>
<ul>
<li><i class="fa-regular fa-square fa-fw" aria-hidden="true"></i> 待补充</li>
</ul>
<h2 id="database">Database</h2>
<ul>
<li>禁止使用 Table Join。</li>
<li>禁止使用 Oracle Trigger。</li>
<li>禁止将查询数据库的 SQL 放在循环中查询</li>
</ul>
<h3 id="sql-撰写">SQL 撰写</h3>
<ul>
<li>属于 SQL 语法使用大写（SELECT，WHERE，INSERT etc..）</li>
<li>属于使用者自己定义的使用小写（表名 table name，字段名 column name etc..）</li>
<li>表名、字段名前后需加上 `</li>
</ul>
<p><strong>Example</strong></p>
<div class="highlight" id="id-14"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sql" data-lang="sql"><span class="line"><span class="cl"><span class="k">INSERT</span><span class="w"> </span><span class="k">INTO</span><span class="w"> </span><span class="o">`</span><span class="k">user</span><span class="o">`</span><span class="w"> </span><span class="k">VALUES</span><span class="p">(</span><span class="s1">&#39;a&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;b&#39;</span><span class="p">);</span></span></span></code></pre></td></tr></table>
</div>
</div><h2 id="统一用词">统一用词</h2>
<blockquote>
<p>系统中常用词，例如弹出框按钮、搜索框等，仅为举例，不限与此。</p>
</blockquote>
<table>
<thead>
<tr>
<th style="text-align:left">用词</th>
<th style="text-align:left">统一</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left">最后、最终</td>
<td style="text-align:left">最后</td>
</tr>
<tr>
<td style="text-align:left">关闭、Cancel、取消</td>
<td style="text-align:left">取消</td>
</tr>
<tr>
<td style="text-align:left">存储、保存、修改、OK、确定</td>
<td style="text-align:left">确定</td>
</tr>
<tr>
<td style="text-align:left">搜寻、查询、查找、搜索</td>
<td style="text-align:left">搜索</td>
</tr>
</tbody>
</table>
]]></description></item></channel></rss>