文章目录
1、web开发模式
1、前后端混合开发(模板语言: DTL),处理很多前端问题
2、前后端分离: 前端是一个项目,后端是一个项目,前后端联调
全栈开发
3、前端: 不仅仅指web前端,还有移动端,小程序等
web: vue,react,html+css+jquery
移动端: ios(object c,swift),安卓(java,Kotlin)
小程序: 微信把js,html,css封装了
发展到现在: 大前端概念
flutter: Dart
uni-app: vue框架
4、前后端分离的项目,后端只需要返回json格式字符串即可
2、restful规范
2.1、定义
REST全称是Representational State Transfer,中文意思是表述(编者注: 通常译为表征性状态转移), 它首次出现在2000年Roy Fielding的博士论文中
RESTful是一种定义Web API接口的设计风格,尤其适用于前后端分离的应用模式中
这种风格的理念认为后端开发任务就是提供数据的,对外提供的是数据资源的访问接口,所以在定义接口时,客户端访问的URL路径就表示这种要操作的数据资源
事实上,我们可以使用任何一个框架都可以实现符合restful规范的API接口
2.2、特点
1、数据的安全保障
url链接一般都采用https协议进行传输
注: 采用https协议,可以提高数据交互过程中的安全性
2、接口特征表现
用api关键字标识接口url
https://api.baidu.com
https://www.baidu.com/api
注: 看到api字眼,就代表该请求url链接是完成前后台数据交互的
3、多版本共存: url链接中标识接口版本
在url链接中标识版本
https://api.baidu.com/v1
https://api.baidu.com/v2
注: url链接中的v1、v2就是不同版本的体现(只有在一种数据资源有多版本情况下)
4、数据即是资源,均使用名词(可复数)
接口一般都是完成前后台数据的交互,交互的数据我们称之为资源
一般提倡用资源的复数形式,不要使用动词
如查询书籍:
https://api.baidu.com/books/
https://api.baidu.com/get_all_books/ # 错误示范
注: 一般提倡用资源的复数形式,在url链接中奖励不要出现操作资源的动词,错误示范
特殊的接口可以出现动词,因为这些接口一般没有一个明确的资源,或是动词就是接口的核心含义
https://api.baidu.com/place/search
https://api.baidu.com/login
5、资源操作由请求方式决定(method)
操作资源一般都会涉及到增删改查,我们提供请求方式来标识增删改查动作
https://api.baidu.com/books get请求: 获取所有书
https://api.baidu.com/books/1 get请求: 获取主键为1的书
https://api.baidu.com/books post请求: 新增一本书书
https://api.baidu.com/books/1 put请求: 整体修改主键为1的书
https://api.baidu.com/books/1 patch请求: 局部修改主键为1的书
https://api.baidu.com/books/1 delete请求: 删除主键为1的书
6、过滤,通过在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: 指定筛选条件
7、响应状态码
正常响应
响应状态码2xx
200: 常规请求
201: 创建成功
重定向响应
响应状态码3xx
301: 永久重定向
302: 暂时重定向
客户端异常
响应状态码4xx
403: 请求无权限
404: 请求路径不存在
405: 请求方法不存在
服务器异常
响应状态码5xx
500: 服务器异常
8、错误处理,应返回错误信息,error当做key,返回结果中带错误信息
{'code':100,'msg':'因为xx原因失败'}
9、返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范
GET /collection: 返回资源对象的列表(数组)
GET /collection/resource: 返回单个资源对象
POST /collection: 返回新生成的资源对象
PUT /collection/resource: 返回完整的资源对象
PATCH /collection/resource: 返回完整的资源对象
DELETE /collection/resource: 返回一个空文档
10、需要url请求的资源需要访问资源的请求链接
# Hypermedia API,RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么
{
"status": 0,
"msg": "ok",
"results":[
{
"name":"肯德基(罗餐厅)",
"img": "https://image.baidu.com/kfc/001.png"
}
...
]
}
# 比较好的接口返回
# 响应数据要有状态码、状态信息以及数据本身
{
"status": 0,
"msg": "ok",
"results":[
{
"name":"肯德基(罗餐厅)",
"location":{
"lat":31.415354,
"lng":121.357339
},
"address":"月罗路2380号",
"province":"上海市",
"city":"上海市",
"area":"宝山区",
"street_id":"339ed41ae1d6dc320a5cb37c",
"telephone":"(021)56761006",
"detail":1,
"uid":"339ed41ae1d6dc320a5cb37c"
}
...
]
}
3、api接口
通过网络,规定了前后台信息交互规则的url链接,也就是前后台信息交互的媒介
Web API接口和一般的url链接还是有区别的,Web API接口简单概括有下面四大特点:
- url:长得像返回数据的url链接
- https://api.map.baidu.com/place/v2/search
- 请求方式:get、post、put、patch、delete
- 采用get方式请求上方接口
- 请求参数:json或xml格式的key-value类型数据
- ak:6E823f587c95f0148c19452139b99295
- region:上海
- query:肯德基
- output:json
- 响应结果:json或xml格式的数据
- 上方请求参数的output参数值决定了响应数据的格式
{
"status":0,
"message":"ok",
"results":[
{
"name":"肯德基(罗餐厅)",
"location":{
"lat":31.415354,
"lng":121.357339
},
"address":"月罗路2380号",
"province":"上海市",
"city":"上海市",
"area":"宝山区",
"street_id":"339ed41ae1d6dc320a5cb37c",
"telephone":"(021)56761006",
"detail":1,
"uid":"339ed41ae1d6dc320a5cb37c"
}
...
]
}
4、postman接口测试工具
postman是一款接口调试工具,是一款免费的可视化软件,同时支持各种操作系统平台,是测试接口的首选工具
- 工作面板
- 简易的get请求
- 简易的post请求
- 案例:请求百度地图接口
5、django rest framework
5.1、定义
Django REST framework 框架是一个用于构建Web API 的强大而又灵活的工具。
通常简称为DRF框架或REST framework
DRF框架是建立在Django框架基础之上,由Tom Christie大牛二次开发的开源项目
在序列化与反序列化时,虽然操作的数据不尽相同,但是执行的过程却是相似的,也就是说这部分代码是可以复用简化编写的
在开发REST API的视图中,虽然每个视图具体操作的数据不同,但增、删、改、查的实现流程基本套路化,所以这部分代码也是可以复用简化编写的:
增: 校验请求数据 -> 执行反序列化过程 -> 保存数据库 -> 将保存的对象序列化并返回
删: 判断要删除的数据是否存在 -> 执行数据库删除
改: 判断要修改的数据是否存在 -> 校验请求的数据 -> 执行反序列化过程 -> 保存数据库 -> 将保存的对象序列化并返回
查: 查询数据库 -> 将数据序列化并返回
特点:
提供了定义序列化器Serializer的方法,可以快速根据 Django ORM 或者其它库自动序列化/反序列化
提供了丰富的类视图、Mixin扩展类,简化视图的编写
丰富的定制层级:函数视图、类视图、视图集合到自动生成 API,满足各种需要
多种身份认证和权限认证方式的支持
内置了限流系统
直观的 API web 界面
可扩展性,插件丰富
5.2、drf的安装和使用
1、安装drf: pip3 install djangorestframework
2、settings.py注册app: INSTALLED_APPS = [..., 'rest_framework']
3、基于cbv完成满足restful规范的接口
5.3、cbv源码分析
from rest_framework.response import Response
from rest_framework.views import APIView
# drf: APIView的源码分析
def as_view(cls, **initkwargs):
# 这句话执行完成返回 view闭包函数的内存地址
view = super().as_view(**initkwargs) # 调用父类(View)的as_view
view.cls = cls
view.initkwargs = initkwargs
view=csrf_exempt(view) # 局部禁用csrf
return view
# 装饰器的使用方式
@csrf_exempt # 等价于 view=csrf_exempt(view)
def view():
pass
# 请求来了,会执行上面返回的view() ----> self.dispatch(APIView的dispatch)
# APIView的dispatch方法
def dispatch(self, request, *args, **kwargs):
# 把原生的request,封装进新的Request对象(drf的Request)
request = self.initialize_request(request, *args, **kwargs)
self.request = request
try:
# 重点(频率,认证,权限...)
self.initial(request, *args, **kwargs)
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
# 这个request是新的requst,是drf中Request对象
# response是原生response
response = handler(request, *args, **kwargs)
except Exception as exc:
# 全局异常
response = self.handle_exception(exc)
# 把原生response包装了一下
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response
6、APIview源码分析
1、APIview的as_view
内部还是执行了View的闭包函数view
禁用掉了csrf
一切皆对象,函数也是对象 函数地址.属性=值
2、原生View类中过的as_view中的闭包函数view
本质执行了self.dispatch(request, *args, **kwargs),执行的是APIView的dispatch
3、APIView的dispatch
def dispatch(self, request, *args, **kwargs):
# DRF的Request类的对象,内部有request._request,是原生request
request = self.initialize_request(request, *args, **kwargs)
self.request = request
try:
self.initial(request, *args, **kwargs)
'''
#认证,权限,频率
self.perform_authentication(request)
self.check_permissions(request)
self.check_throttles(request)
'''
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
response = handler(request, *args, **kwargs)
except Exception as exc:
# 全局的异常捕获
response = self.handle_exception(exc)
# 把视图函数(类)返回的response,又包装了一下
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response
7、Request类分析
request._request: 原生request
request.data : post请求提交的数据(urlencoded,json,formdata)
request.user : 不是原生的user了
request.query_params: 原生的request.GET,为了遵循restful规范
requset.FILES: 新的
通过重写__getattr__,新的request.原来所有的属性和方法,都能直接拿到
def __getattr__(self, attr):
return getattr(self._request, attr)