restful 协议:面向资源软件架构风格
API
定义
一些预先定义的函数,目的是能够让应用程序或开发人员能够具有访问指定网络资源的能力,而无需关心访问的远吗以及内部的工作机制细节。
RESTful
- REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”
- REST从资源的角度类审视整个网络,它将分布在网络中某个节点的资源通过URL进行标识,客户端应用通过URL来获取资源的表征,获得这些表征致使这些应用转变状态
- REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”
- 所有的数据,不过是通过网络获取的还是操作(增删改查)的数据,都是资源,将一切数据视为资源是REST区别与其他架构风格的最本质属性
- 对于REST这种面向资源的架构风格,有人提出一种全新的结构理念,即:面向资源架构(ROA:Resource Oriented Architecture
概念
在RESTful架构中认为所有一切都是资源,每个资源有对应的URI标识;
处理资源的操作有:
操作名称 | 请求动作名称 |
---|---|
GET | 获取资源 |
POST | 添加资源 |
PUT | 修改资源(非严格遵行RESTful架构) |
UPDATE/PATCH | 修改资源(严格遵行RESTful架构) |
DELETE |
删除资源 |
客户端通过以上4种http动词,对服务器资源进行操作,实现“表现层状态转化”;
【注意】
只是一种架构而不是标准,提供设计原则和约束条件。
适用于客户端与服务器交互类的软件,这是因为它更加简洁、有层次、更利于实现缓存等机制;
状态码
服务器向用户返回的状态吗和提示信息,常见的有以下部分:
- 2XX:这一类型的状态码,代表请求已成功被服务器接收、理解、并接受。
- 3xx重定向:这类状态码代表需要客户端采取进一步的操作才能完成请求。通常,这些状态码用来重定向,后续的请求地址(重定向目标)在本次响应的Location域中指明。当且仅当后续的请求所使用的方法是GET或者HEAD时,用户浏览器才可以在没有用户介入的情况下自动提交所需要的后续请求。客户端应当自动监测无限循环重定向(例如:A→B→C→……→A或A→A),因为这会导致服务器和客户端大量不必要的资源消耗。按照HTTP/1.0版规范的建议,浏览器不应自动访问超过5次的重定向。
- 4xx客户端错误:这类的状态码代表了客户端看起来可能发生了错误,妨碍了服务器的处理。除非响应的是一个HEAD请求,否则服务器就应该返回一个解释当前错误状况的实体,以及这是临时的还是永久性的状况。这些状态码适用于任何请求方法。浏览器应当向用户显示任何包含在此类错误响应中的实体内容。
- 5xx服务器错误:表示服务器无法完成明显有效的请求。这类状态码代表了服务器在处理请求的过程中有错误或者异常状态发生,也有可能是服务器意识到以当前的软硬件资源无法完成对请求的处理。除非这是一个HEAD请求,否则服务器应当包含一个解释当前错误状态以及这个状况是临时的还是永久的解释信息实体。浏览器应当向用户展示任何在当前响应中被包含的实体。这些状态码适用于任何响应方法。
状态码 | 含义 | 备注 |
200 OK | 请求已成功,请求所希望的响应头或数据体将随此响应返回 | 实际响应将取决于所使用的请求方法。在GET请求中,响应将包含与请求的资源相对应的实体。在POST请求中,响应将包含描述或操作结果的实体 |
201 Created | 请求已经被实现,而且有一个新的资源已经一句请求的需要而创建,且其url已经随Location头信息返回 | 假如需要的资源无法及时创建的话,应当返回‘202 Accepted’ |
202Accepted | 服务器已接受请求,但尚未处理。最终该请求可能会也可能不会被执行,并且可能在处理发生时被禁止。 | |
203 Non-Authoritative Information | 服务器是一个转换代理服务器(transforming proxy,例如网络加速),以200 ok状态码为起源,但回应了原始响应的修改版本 | 自HTTP/1.1起 |
204 No Content | 服务器成功处理了请求,没有返回任何内容 | |
205 Reset Content | 服务器成功处理了请求,但没有返回任何内容 | 与204响应不同,此响应要求请求者重置文档视图 |
206 Partial Content | 服务器已经成功处理了部分GET请求。类似于FlashGet或者迅雷这类的HTTP。下载工具都是使用此类响应实现断点续传或者将一个大文档分解为多个下载段同时下载。 | |
207 Multi-Status | 代表之后的消息体将是一个XML消息,并且可能依照之前子请求数量的不同,包含一系列独立的响应代码。 | (WebDAV;RFC 4918) |
208 Already Reported | DAV绑定的成员已经在(多状态)响应之前的部分被列举,且未被再次包含。 | |
226 IM Used | 服务器已经满足了对资源的请求,对实体请求的一个或多个实体操作的结果表示。 | |
300 Multiple Choices | 被请求的资源有一系列可供选择的回馈信息,每个都有自己特定的地址和浏览器驱动的商议信息。 | 用户或浏览器能够自行选择一个首选的地址进行重定向。 |
301 Moved Permanently | 被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个URI之一。 | |
302 Found | 要求客户端执行临时重定向(原始描述短语为“Moved Temporarily”)。由于这样的重定向是临时的,客户端应当继续向原有地址发送以后的请求。 | 只有在Cache-Control或Expires中进行了指定的情况下,这个响应才是可缓存的。 |
303 See Other | 对应当前请求的响应可以在另一个URI上被找到,当响应于POST(或PUT / DELETE)接收到响应时,客户端应该假定服务器已经收到数据,并且应该使用单独的GET消息发出重定向。 | |
304 Not Modified | 表示资源未被修改,因为请求头指定的版本If-Modified-Since或If-None-Match。在这种情况下,由于客户端仍然具有以前下载的副本,因此不需要重新传输资源。 | |
305 Use Proxy |
被请求的资源必须通过指定的代理才能被访问。Location域中将给出指定的代理所在的URI信息,接收者需要重复发送一个单独的请求,通过这个代理才能访问相应资源。只有原始服务器才能创建305响应。许多HTTP客户端(像是Mozilla和Internet Explorer)都没有正确处理这种状态代码的响应,主要是出于安全考虑。
|
|
306 Switch Proxy |
是指“后续请求应使用指定的代理”。
|
最新版的规范中,306状态码已经不再被使用。 |
307 Temporary Redirect | 在这种情况下,请求应该与另一个URI重复,但后续的请求应仍使用原始的URI。 与302相反,当重新发出原始请求时,不允许更改请求方法。 例如,应该使用另一个POST请求来重复POST请求 | |
308 Permanent Redirect |
请求和所有将来的请求应该使用另一个URI重复。 307和308重复302和301的行为,但不允许HTTP方法更改。 例如,将表单提交给永久重定向的资源可能会顺利进行。
|
|
400 Bad Request | 由于明显的客户端错误(例如,格式错误的请求语法,太大的大小,无效的请求消息或欺骗性路由请求),服务器不能或不会处理该请求。 | |
401 Unauthorized | 类似于403 Forbidden,401语义即“未认证”,即用户没有必要的凭据。该状态码表示当前请求需要用户验证。该响应必须包含一个适用于被请求资源的WWW-Authenticate信息头用以询问用户信息。客户端可以重复提交一个包含恰当的Authorization头信息的请求。 | |
402 Payment Required | 该状态码是为了将来可能的需求而预留的。该状态码最初的意图可能被用作某种形式的数字现金或在线支付方案的一部分,但几乎没有哪家服务商使用,而且这个状态码通常不被使用。如果特定开发人员已超过请求的每日限制,Google Developers API会使用此状态码。 | |
403 Forbidden | 服务器已经理解请求,但是拒绝执行它。如果这不是一个HEAD请求,而且服务器希望能够讲清楚为何请求不能被执行,那么就应该在实体内描述拒绝的原因。当然服务器也可以返回一个404响应,假如它不希望让客户端获得任何信息。 | 与401响应不同的是,身份验证并不能提供任何帮助,而且这个请求也不应该被重复提交。 |
404 Not Found |
请求失败,请求所希望得到的资源未被在服务器上发现,但允许用户的后续请求。没有信息能够告诉用户这个状况到底是暂时的还是永久的。假如服务器知道情况的话,应当使用410状态码来告知旧资源因为某些内部的配置机制问题,已经永久的不可用,而且没有任何可以跳转的地址。404这个状态码被广泛应用于当服务器不想揭示到底为何请求被拒绝或者没有其他适合的响应可用的情况下。
|
|
405 Method Not Allowed | 请求行中指定的请求方法不能被用于请求相应的资源。该响应必须返回一个Allow头信息用以表示出当前资源能够接受的请求方法的列表。例如,需要通过POST呈现数据的表单上的GET请求,或只读资源上的PUT请求。 | |
406 Not Acceptable | 请求的资源的内容特性无法满足请求头中的条件,因而无法生成响应实体,该请求不可接受。 | |
407 Proxy Authentication Required | 与401响应类似,只不过客户端必须在代理服务器上进行身份验证。 | |
408 Request Timeout | 请求超时。根据HTTP规范,客户端没有在服务器预备等待的时间内完成一个请求的发送,客户端可以随时再次提交这一请求而无需进行任何更改。 | |
409 Conflict | 表示因为请求存在冲突无法处理该请求,例如多个同步更新之间的编辑冲突。 | |
410 Gone | 表示所请求的资源不再可用,将不再可用。当资源被有意地删除并且资源应被清除时,应该使用这个。在收到410状态码后,用户应停止再次请求资源。但大多数服务端不会使用此状态码,而是直接使用404状态码。 | |
500 Internal Server Error | 通用错误消息,服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。没有给出具体错误信息。 | |
501 Not Implemented | 服务器不支持当前请求所需要的某个功能。当服务器无法识别请求的方法,并且无法支持其对任何资源的请求。 | |
502 Bad Gateway | 作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。 | |
503 Service Unavailable | 由于临时的服务器维护或者过载,服务器当前无法处理请求。这个状况是暂时的,并且将在一段时间以后恢复。如果能够预计延迟时间,那么响应中可以包含一个Retry-After头用以标明这个延迟时间。如果没有给出这个Retry-After信息,那么客户端应当以处理500响应的方式处理它。 | |
504 Gateway Timeout | 作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到响应。注意:某些代理服务器在DNS查询超时时会返回400或者500错误。 |
RESTful API设计
- API与用户的通信协议,总是使用HTTPs协议。
- 域名
- https://api.example.com 尽量将API部署在专用域名(会存在跨域问题)
- https://example.org/api/ API很简单
- 版本
- URL,如:https://api.example.com/v1/
- 请求头 跨域时,引发发送多次请求
- 路径,视网络上任何东西都是资源,均使用名词表示(可复数)
- https://api.example.com/v1/zoos
- https://api.example.com/v1/animals
- https://api.example.com/v1/employees
- method
- GET :从服务器取出资源(一项或多项)
- POST :在服务器新建一个资源
- PUT :在服务器更新资源(客户端提供改变后的完整资源)
- PATCH :在服务器更新资源(客户端提供改变的属性)
- DELETE :从服务器删除资源
- 过滤,通过在url上传参的形式传递搜索条件
- https://api.example.com/v1/zoos?limit=10:指定返回记录的数量
- https://api.example.com/v1/zoos?offset=10:指定返回记录的开始位置
- https://api.example.com/v1/zoos?page=2&per_page=100:指定第几页,以及每页的记录数
- https://api.example.com/v1/zoos?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序
- https://api.example.com/v1/zoos?animal_type_id=1:指定筛选条件
- 错误处理,状态码是4xx时,应返回错误信息,error当做key。
{ error: "Invalid API key" }
- 返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范。
-
GET /collection:返回资源对象的列表(数组) GET /collection/resource:返回单个资源对象 POST /collection:返回新生成的资源对象 PUT /collection/resource:返回完整的资源对象 PATCH /collection/resource:返回完整的资源对象 DELETE /collection/resource:返回一个空文档
- Hypermedia API,RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。
{"link": { "rel": "collection https://www.example.com/zoos", "href": "https://api.example.com/zoos", "title": "List of zoos", "type": "application/vnd.yourformat+json" }}
关于对rest api的认识
原来web应用程序时,根据URL不同定位到不同视图函数处理。
以前我们刚学习写项目时,增删改查需要写到4个url当接口,而而现在我们只需要写一个url
rest是一种规范:面向资源
# 当我们来介绍rest 规范时候可以从url的顺序来介绍 # http://api.luffycity.com/v1/users # 1 http :协议 # 2 api.luffycity.com :域名 # 3 v1:版本 # 4 users:urls中是名词 5:发送过去有不同的请求方式 即:method不同执行不同函数:get/post/delete/put/patch 6:返回状态码 常见状态码:200/301/302/404/403/500 7:错误信息: { msg: '用户名或密码错误' } def index(request): ret = {'code':1000,'data':None} return HttpResponse('xxx',status=200) 8:返回值: http://api.luffycity.com/v1/users http://api.luffycity.com/v1/users/1 9:条件 http://api.luffycity.com/v1/users?page=1&size=10 PS: 主键ID体现在URL上 10 hyperlink { id: '老司机', age: 18, group: http://www.luffycti.com/api/v1/group/1/ }
django rest framework
10个组件(重点需要了解源码)
按请求进来的顺序 1:路由 请求进来要走路由 2:视图 路由写完就到了视图 3:版本 请求进去源码dispatch里面有4个方法 4:认证 5:权限 6:节流(频率) 7:解析器 发数据需要转换数据类型 8:序列化 需要校验数据(序列化有2个功能:序列化,校验) 9:分页 10:渲染器
知识点
加括号的三种情况
类
函数或者加方法执行
对象
源码后的心得
1:封装的思想:
例如:将认证组件封装request里面,接着就只要requesst。user就能
2:开放,封闭思想(只要改配置即生效)
3:配置:中间件配置
问题:发送邮件、短信、微信提醒
# 文件启动会先运行init文件 import settings import importlib def send_xxxx(content): for path in settings.NOTIFY_LIST: # 'notify.email.Email', # 'notify.msg.Msg', # 'notify.wechat.Wechat' # module_path模块路径 module_path,class_name = path.rsplit('.',maxsplit=1) # importlib.import_module("notify.email") # 根据字符串导入模块:notify.email # importlib module = importlib.import_module(module_path) # 根据类名称去模块中获取类 cls = getattr(module,class_name) # 根据类实例化 obj = cls() obj.send(content)
class Email(object): def __init__(self): pass def send(self): pass
from notify import send_xxxx def run(): send_xxxx('报警') if __name__ == '__main__': pass
NOTIFY_LIST = [ 'notify.email.Email', # 'notify.msg.Msg', 'notify.wechat.Wechat', 'notify.wechat.Wechat', ]
question:你觉得python基础中哪些知识比较重要?
answer:我现在想到的,列表生成式、反射以及面向对象都比较重要,因为我最近在研究django rest-framework的源码,就发现这些知识在源码里面全部都用到了,比如说CBV是通过反射实现的,
比如说认证,原来我对封装的认识还不太够,后来看了这个源码,它里面有一种封装的思想就是把认证这个类封装到了request里面,以后要去用的时候,只需要调用它的方法,由它里边具体完成这个功能
开放封闭原则:
只对配置开放,可以任意修改配置文件,只要修改配置文件,就生效了;
封闭,指的是原代码封闭,添加功能和删除功能的时候,最好不要去改代码,只要改配置就能生效;