RESTful介绍

RESTful规范

​ 编程是数据结构和算法的结合,而在Web类型的App中,我们对于数据的操作请求是通过url来承载的,本文详细介绍了REST规范和CBV请求流程。

​ 编程是数据结构和算法的结合,小程序如简单的计算器,我们输入初始数据,经过计算,得到最终的数据,这个过程中,初始数据和结果数据都是数据,而计算过程是我们所说的广义上的算法。

​ 大程序,如一个智能扫地机器人,我们可以设置打扫的距离,左右摆动的幅度来打扫房间,这里面打扫的举例,摆动幅度,都是数据,而打扫的过程是较为复杂的算法过程,总之,也是算法,即程序的实现方式。

​ 另外,我们还可以设置打扫时间等等初始数据。

​ 总之一句话,编程即数据结构和算法的结合。简单的程序可能不需要跟用户交互数据,但是现代的应用程序几乎都需要跟用户进行交互,不分应用程序类型,不管是CS型还是BS型的程序都是如此,而Python最擅长的Web App即BS型的程序,就是通过url和http来跟用户进行数据交互的,通过url和http请求,用户可以操作服务器端的程序,主要操作分为:增、删、改、查几类。

引入

在开始之前,我们回顾一下咱们之前写过的图书管理系统项目,请仔细回想一下,对于该项目的设计,我们大概是以下面这种方式来实现的

传统url设计风格
  • url各式各样,设计混乱

DRF

理论上来说,这种方式完全可以实现我们的需求,但是一旦项目丰富起来,随着数据量增加,随着各个业务系统之间的逻辑关系不断的复杂,url会越来越复杂,理论上来说,不管是什么类型、什么名称的url都能指向具体的业务逻辑(视图函数),从而实现业务需求,但是如果没有明确的规范,因每个人的思维方式不一样、命名方式不一样而导致的url非常的乱,不方便项目的后期维护和扩展。

  • 对于请求处理成功或者失败的返回信息没有明确的响应信息规范,返回给客户端的信息往往都是很随意的

以上这些情况的出现,导致了很多的问题,让互联网的世界变得杂乱不堪,日益复杂且臃肿。因此http协议创始人警告我们这些凡人们正在错误的使用http协议,除了警告,他还发表了一篇博客,大概意思就是教大家如何正确使用http协议,如何正确定义url,这就是REST(Representational State Transfer),不需要管这几个英文单词代表什么意思,只需要记住下面一句话:

  • 用url唯一定位资源,用Http请求方式(GET, POST, DELETE, PUT)描述用户行为

根据这句话,我们重新定义图书管理系统中的url

RESTful Api设计风格

DRF

可以看到,url非常简洁优雅,不包含任何操作,不包含任何动词,简简单单,用来描述服务器中的资源而已,服务器根据用户的请求方式对资源进行各种操作。而对数据的操作,最常见的就是CRUD(创建,读取,更新,删除),通过不同的请求方式,就足够描述这些操作方式了。如果不够用,Http还有其他的请求方式呢!比如:PATCH,OPTIONS,HEAD, TRACE, CONNECT。

REST定义返回结果

DRF

每一种请求方式的返回结果不同。

REST定义错误信息
{
    "error": "Invalid API key"
}

通过一个字典,返回错误信息。

这就是REST,上图中的url就是根据REST规范进行设计的RESTful api。

概念

REST是一种软件架构设计风格,不是标准,也不是具体的技术实现,只是提供了一组设计原则和约束条件。是目前最流行的 API 设计规范,用于 Web 数据接口的设计。它主要用于客户端和服务器交互类的软件。基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制。2000年,由Roy Fielding在他的博士论文中提出,Roy Fielding是HTTP规范的主要编写者之一。

URL规范

​ 1.不用大写;

​ 2.用中杠 - 不用下杠 _ ;

​ 3.参数列表要encode;

​ 4.URI中的名词表示资源集合,使用复数形式。

​ 5.在RESTful架构中,每个网址代表一种资源(resource),所以网址中不能有动词,只能有名词(特殊情况可以使用动词),而且所用的名词往往与数据库的表格名对应。

restful 规范

       1. 根据method不同,进行不同操作
           GET/POST/PUT/DELETE/PATCH
       2. 面向资源编程
           http://www.nnblog.com/blog
       3. 体现版本
           http://www.nnblog.com/v1/blog
           http://www.nnblog.com/v2/blog     
           https://v4.bootcss.com/
           https://v3.bootcss.com/
       4. 体现是API
           http://www.nnblog.com/api/v1/blog
           http://www.nnblog.com/api/v2/blog  
            
           http://api.nnblog.com/v1/salary
           http://api.luffycity.com/v2/blog   
       5. https
           https://www.nnblog.com/api/v1/blog
           https://www.nnblog.com/api/v2/blog   
       6. 响应式设置状态码
           200
           300
           400
           500
           return HttpResponse('adfasdf',status=300)
       7. 条件
           https://www.nnblog.com/api/v2/blog?page=1&size=10
       8. 返回值
           https://www.nnblog.com/api/v2/salary
           GET: 所有列表
           {
               code: 10000,
               data: [   
                   {'id':1,'title':'a'},
                   {'id':1,'title':'b'},
                   {'id':1,'title':'c'},
               ]
           }
                
           POST: 返回新增的数据
               {'id':1,'title':'高亮'}
                
           https://www.nnblog.com/api/v2/salary/1/
           GET: 获取单条数据
                   {'id':1,'title':'d'}
           PUT:更新
                   {'id':1,'title':'e'}
           PATCH: 局部更新
                   {'id':1,'title':'f'}
           DELETE:删除          
       9. 返回错误信息
           {
               code: 100001,
               error: 'xxx错误'
           }      
       10. Hypermedia API
           ret = {
               code: 1000,
               data:{
                   id:1,
                   name:'jiumo',
                   depart_id:http://www.nnblog.com/api/v1/blog/8/
               }
           }
Request
url唯一定位资源(数据),http请求方式描述用户行为
	GET    127.0.0.1:8000/books/     # 获取所有数据
	POST   127.0.0.1:8000/books/     # 添加一条数据
	PUT    127.0.0.1:8000/books/{id} # 修改一条数据
	DELETE 127.0.0.1:8000/books/{id} # 删除一条数据
	GET    127.0.0.1:8000/books/{id} # 获取单条数据
Response
返回数据规范
	GET    127.0.0.1:8000/books/     # 获取所有数据  [ {}, {}, {}]
	POST   127.0.0.1:8000/books/     # 添加一条数据  {}
	PUT    127.0.0.1:8000/books/{id} # 修改一条数据  {}
	DELETE 127.0.0.1:8000/books/{id} # 删除一条数据  ""
	GET    127.0.0.1:8000/books/{id} # 获取单条数据  {}
	
错误信息
	{ "error": "error_message" }
状态码
服务器向用户返回的状态码和提示信息,常见的有以下一些(方括号中是该状态码对应的HTTP动词):

	200 OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。
	201 CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
	202 Accepted - [*]:表示一个请求已经进入后台排队(异步任务)
	204 NO CONTENT - [DELETE]:用户删除数据成功。

	400 INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。
	401 Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。
	403 Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。
	404 NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。
	406 Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。
	410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。
	422 Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。

	500 INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。

URI失效:
	随着系统发展,总有一些API失效或者迁移,对失效的API,返回404 not found 或 410 gone;对迁移的API,返回 301重定向。

那么,Django RestFramework与rest有什么关系呢?

其实,DRF(Django RestFramework)是一套基于Django开发的、帮助我们更好的设计符合REST规范的Web应用的一个Django App,所以,本质上,它是一个Django App。

原文地址:https://www.cnblogs.com/jiumo/p/10098145.html