Node.js 结合express模块可以用于快速开发一个轻量的,易于扩展的Web服务器。
但是由于 Node.js 处理JavaScript程序的线程只有一个v8主线程,所以不适合处理CPU密集型的任务。这导致了 Node.js 作为后端服务器的竞争力降低。
但是 Node.js 从其命名就可以看出它的理想是作为网络中的一个“节点",而不是一个"端"。节点更注重的是数据的传递,端注重的是数据的处理。
目前,市场对于Node.js的定位更多体现在:开发RESTful API服务器,开发SSR 服务端渲染网页,开发Web Socket,开发前端工程化工具。
认识RESTful
什么是 REST API 一文读懂 (RESTful API)_哔哩哔哩_bilibili
API大家都知道,是接口的意思。
那么RESTful是啥意思呢?很惬意的?非也。
REST其实是一个缩写词汇:Representational State Transfer,翻译一下就是:(具有代表性的)(状态)(转移)
状态转移,我们都隐约能理解为:前后端交互的数据转移,比如浏览器HTTP POST提交用户数据到后端,后端收到用户数据就会将其转存到数据库。这个过程中,就发送了用户数据的转移。但是有时候,前后端交互中,并没有涉及到数据的传递,比如浏览器发送一个HTTP DELETE请求到后端,且没有携带任何数据,后端收到DELETE请求后,直接删除对应资源,之后只会响应一个删除成功状态给前端。这个过程中,其实没有前端并没有传递什么实际性的数据给后端,但是后端却发生了非幂等性的行为。对于这种无数据的交互,其实就属于状态的转移。
那么“具有代表性的” 又如何理解呢?
之前的一个项目中,有幸参加过SE的工作,设计过API的URL,但是所在部件没有采用RESTful规范,API URL的设计要求见名知意,所以就出现了如下API URL:
/api/getCustomer
/api/setCustomer
/api/createCustomer
/api/deleteCustomer
/api/getCustomerById
分析以上URL,可以发现操作的资源都指向了customer,但是由于操作方式的不同,以及操作条件不同形成了多个URL,并且URL整体变得很长,如果按照RESTful规范设计URL的话,可以简化为
GET | /api/customer |
PUT / PATCH | |
POST | |
DELETE | |
GET | /api/customer/:id |
上面的URL设计就很精简,一些修饰性的语义交给了HTTP METHOD,URL只保留了最具有代表性的部分/api/customer。
当然所在部件不使用RESTful规范是有原因的,因为该部件直接对接外部第三方,不在安全域内,有被黑客攻击的危险,所以虽然采用了HTTP协议,但是只使用POST以及GET请求方式,导致无法利用HTTP METHOD来分担URL语义描述工作。
相信大家此时应该对:具有代表性的状态的转移,即REST,有了一定的了解。
REST只是一种API服务器的表现层设计规范。
RESTful接口URL设计规范
协议
通信协议不限,但是通常使用HTTP或HTTPS,建议使用安全的HTTPS协议
域名
最好有API服务器的专用域名,并且要保证在公司网络安全域内
https://api.example.com/
版本
接口API的版本也是需要考虑的,通常将版本信息放在URL中
https://api.example.com/v1/
资源标识
每个接口都应该对应一个资源,后端服务器的资源通常指的就是数据库数据所在表或集合,所以理论上,为了方便见名知意,URL中资源标识命名应该和数据库对应的表名或者集合名相同。
https://api.example.com/v1/user
资源操作
资源操作无非就是指:增删改查
RESTful设计规范提倡将“增删改查”这种语义化工作交给HTTP METHOD,而不是放到URL中,比如获取用户列表使用GET,创建用户使用POST,修改用户信息使用PUT,删除用户使用DELETE。
常用的HTTP METHOD含义
HTTP METHOD | 服务器操作 | 数据库操作 |
GET | 从服务器获取资源(一个或多个) | 查询 |
POST | 在服务器上创建一个或多个资源 | 插入 |
PUT | 在服务器更新资源(客户端提供资源的完整信息给服务器) | 完整更新 |
PATCH | 在服务器更新资源(客户端提供资源的部分信息给服务器) | 局部更新 |
DELETE | 从服务器删除资源 | 删除 |
HEAD | 获取资源的元数据(描述性数据) | |
OPTIONS | 获取信息,关于资源的哪些属性是客户端可以改变的 |
查询过滤
GET查询操作是比较特殊的操作,对于服务器来说,查询操作是幂等的,是安全的。但是当查询到的结果中资源过多时,很容易造成内存溢出,所以限制查询的结果数量很有必要。
RESTful设计规范建议使用GET查询大数据量结果时,可以利用URL查询字符串,如
https://api.example.com/v1/user?limit=5&pagenum=1
操作结果状态
RESTful规范建议利用HTTP响应状态码来描述操作结果的状态,而不是自定义状态码。
HTTP响应状态码可以分为如下几类:
状态码 | 状态码英文名称 | 中文描述 |
---|---|---|
100 | Continue | 继续。客户端应继续其请求 |
101 | Switching Protocols | 切换协议。服务器根据客户端的请求切换协议。只能切换到更高级的协议,例如,切换到HTTP的新版本协议 |
200 | OK | [GET] 服务器成功返回用户请求的数据,幂等操作。 |
201 | Created | [POST / PUT / PATCH] 用户新建或修改数据成功。 |
202 | Accepted | [*] 表示一个请求已经进入后台排队(异步任务) |
203 | Non-Authoritative Information | 非授权信息。请求成功。但返回的meta信息不在原始的服务器,而是一个副本 |
204 | No Content | [DELETE] 服务器删除数据成功 |
205 | Reset Content | 重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域。常用于PUT请求 |
206 | Partial Content | 部分内容。服务器成功处理了部分GET请求 |
300 | Multiple Choices | 多种选择。请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择 |
301 | Moved Permanently | 永久移动。请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替 |
302 | Found | 临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URI |
303 | See Other | 查看其它地址。与301类似。使用GET和POST请求查看 |
304 | Not Modified | 未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源。客户端通常会缓存访问过的资源,通过提供一个头信息指出客户端希望只返回在指定日期之后修改的资源 |
305 | Use Proxy | 使用代理。所请求的资源必须通过代理访问 |
306 | Unused | 已经被废弃的HTTP状态码 |
307 | Temporary Redirect | 临时重定向。与302类似。使用GET请求重定向 |
400 | Bad Request | [POST / PUT / PATCH] 用户发出的请求有错误,服务器没有进行新建或修改数据的操作,即保证了幂等。 |
401 | Unauthorized | [*] 表示用户没有权限(令牌,用户名,密码错误) |
402 | Payment Required | 保留,将来使用 |
403 | Forbidden | [*] 用户已有权限,但是资源的访问是被禁止的 |
404 | Not Found | [*] 服务器无法根据客户端的请求找到资源 |
405 | Method Not Allowed | 客户端请求中的方法被禁止 |
406 | Not Acceptable | 用户请求的格式不可得,比如用户想要JSON格式响应,但是只有XML格式 |
407 | Proxy Authentication Required | 请求要求代理的身份认证,与401类似,但请求者应当使用代理进行授权 |
408 | Request Time-out | 服务器等待客户端发送的请求时间过长,超时 |
409 | Conflict | 服务器完成客户端的 PUT 请求时可能返回此代码,服务器处理请求时发生了冲突 |
410 | Gone | [GET] 客户端请求的资源已经不存在。410不同于404,如果资源以前有现在被永久删除了可使用410代码,网站设计人员可通过301代码指定资源的新位置 |
411 | Length Required | 服务器无法处理客户端发送的不带Content-Length的请求信息 |
412 | Precondition Failed | 客户端请求信息的先决条件错误 |
413 | Request Entity Too Large | 由于请求的实体过大,服务器无法处理,因此拒绝请求。为防止客户端的连续请求,服务器可能会关闭连接。如果只是服务器暂时无法处理,则会包含一个Retry-After的响应信息 |
414 | Request-URI Too Large | 请求的URI过长(URI通常为网址),服务器无法处理 |
415 | Unsupported Media Type | 服务器无法处理请求附带的媒体格式 |
416 | Requested range not satisfiable | 客户端请求的范围无效 |
417 | Expectation Failed | 服务器无法满足Expect的请求头信息 |
500 | Internal Server Error | 服务器内部错误,无法完成请求 |
501 | Not Implemented | 服务器不支持请求的功能,无法完成请求 |
502 | Bad Gateway | 作为网关或者代理工作的服务器尝试执行请求时,从远程服务器接收到了一个无效的响应 |
503 | Service Unavailable | 由于超载或系统维护,服务器暂时的无法处理客户端的请求。延时的长度可包含在服务器的Retry-After头信息中 |
504 | Gateway Time-out | 充当网关或代理的服务器,未及时从远端服务器获取请求 |
505 | HTTP Version not supported | 服务器不支持请求的HTTP协议的版本,无法完成处理 |
操作结果数据
操作结果数据,即API接口的返回,RESTful要求API接口返回不应该是纯文本字符串,而是结构化数据,比如JSON数据。
比如
GET https://api.example.com/v1/customer 返回的应该是一个JSON数组
GET https://api.example.com/v1/customer/1 返回的应该是一个JSON对象
DELETE https://api.example.com/v1/customer/1 返回的应该空