目前主流的 Web 开发模式有两种,分别是:
前后端不分离的情况,小项目独立编写前端后端所有内容,大些项目可以前端人员编写完成后交予后端人员使
用模板语法类似于 dtl、jsp、php 等渲染,但是浏览器中只有 html、css、js,如下图所示
前后端分离的情况是现在的主流,前端人员与后端人员只需要编写自己对应部分即可。但是前后端分离的情况
下就不能使用模板语法,此时有了一个 API 接口的观念,如下图所示
API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件的以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。API除了有应用“应用程序接口”的意思外,还特指 API的说明文档,也称为帮助文档。
简单来说,API接口就是前后端信息交互的媒介。预先定义的函数逻辑,通过其他系统请求访问该接口可以获
得结果,例如通过微博的开放API接口可以实现某一些功能需求。
微博开放 API 接口
前端请求的url由谁来写
url 主要有后台来写,写完给前端;
如果后台查询数据,需要借助查询条件才能查询前端需要的数据时后台会要求前端提供相关的的查询参数,这里查询的参数就是url请求的参数;参数前面用 ?
连接 , 几个参数中间 &
号连接;
接口文档主要由谁来写
接口文档主要由后台开发者来设计修改。前端开发者起到了辅助的作用;
因为直接跟数据打交道的就是后台,后台是最清楚,数据库里面有什么数据,能返回什么数据
前端只是接口文档的使用者,使用过程中,发现返回的数据不对,则需要跟后台进行商量,由后台来修改;
前端不要随意更改接口文档,除非在取得后台开发人员的同意的情况下;
前端开发与后台交互的数据格式主要是什么
主要格式有四种:xml json form iframe
,现在最常用的就是 json
格式
由于前后端分离,接口的大量使用,编写接口的规范越来越重要,一套良好的接口规范可以提升工作效率,减少沟通障碍。通常我们都会采用RestfulApi
方式来提供接口,使用JSON
来传输数据。
Api设计6要素
https 数据交互
由于传输的数据很容易被偷窥、被抓包、被伪造。可以使用 HTTPS 加密传输或者如下方法:
token令牌认证(jwt)、时间戳超时验证+签名算法字符串、URL签名(算法,非对称算法)
数据脱敏(防范数据库数据泄露)、IP黑/白名单(服务器层面的限制,apache、nginx)、oAuth2.0。
接口地址中带api标识
可以加在域名中例如 https://api.baidu.com/
也可以加在地址中例如 https://www.baidu.com/api
接口地址中标识版本标识
版本标识可以在例如在版本升级的时候,对同一个功能旧的接口和新的接口进行区分。使用数字或者 v+数字
的形式例如 https://api.baidu.com/v1
、https://api.weibo.com/2/users/show.json
尽量不要有动词
在接口地址中尽量不要有动词,使用名词表示。例如https://api.baidu.com/v1/delete-books
中的 delete 尽量不要出现。
请求方式决定如何对资源进行操作
对于资源,一般的操作是增删改查。使用对一个接口使用不同的请求方式来表示不同的操作。
例如
GET: 从服务器获取资源(一项或多项)(查)
POST: 在服务器新建一个资源(增)
PUT: 在服务器更新资源,服务器返回完整的属性(改)
DELETE: 从服务器删除资源(删)
地址中带参数
当后台需要参数进行资源的操作时,需要在地址中添加参数便于后台操作。
例如 https://api.baidu.com/v1/books?name=红楼梦
响应状态码
成功发送的请求必有响应(响应可能没有响应体,但是状态码肯定有),每个响应都会有一个状态码。在Restful风格编写接口时常见的HTTP请求状态码有
状态码 | 含义 | 说明 |
---|---|---|
200 | OK | 操作成功, 并返回数据 |
400 | Bad Request | 请求语法错误 |
403 | Forbidden | 请求没有权限的资源 |
404 | Not Found | 没有找到请求的资源 |
405 | Method Not Allowed | 请求动词使用错误 |
500 | Internal Server Error | 服务器(配置)内部错误 |
响应中带错误信息
如果状态码是4xx或者5xx,通常以json格式告诉客户端对应的错误信息。
类似于 {code:999,msg:登陆失败}
服务器返回结果
GET /collection/resource:返回单个资源对象
POST /collection:返回新生成的资源对象
PUT /collection/resource:返回完整的资源对象
PATCH /collection/resource:返回完整的资源对象
DELETE /collection/resource:返回一个空文档
响应中带链接地址
在响应中也可以加入链接地址,例如图片资源等等
API 接口可以使用测试工具来发现其中的问题,工具有很多,例如 postman
、postwomen
。postman是一个非常受欢迎的API接口调试工具,但是它的许多高级功能都需要付费才能使用。postwomen 类似于 postman,是一个开源工具。这里使用的是 postman,下载完点击启动即可。
postman 官方下载链接
传输文件有form-data、x-www-form-urlencoded、raw
等方式,在 postman 中在请求体中展示
x-www-form-urlencode格式是 form表单、ajax表单默认的格式,只能是以键值对的形式传参,不能上传文件,代码中必须要把表单默认的 urlencoded 的改成 enctype="multipart/form-date"
raw格式传输文件,可以传输各种类型文件例如text文本文件、json文件、xml文件、html文件等。
其中 json
格式文件代码中只能使用 ajax 来传输,修改为 contentType:application/json
即可。在 postman 中传输方式如下示例
name=xwx&password=666
,该数据是在 request.POST
中获取request.POST
中获取,同时该格式支持传输文件,文件数据在request.FILE
中获取contentType:application/json
传输,并且只能在request.body
取出来DRF 是 djangorestframework 的缩写,它是 django 的一个app(第三方插件),只能用在 django 框架上。其可以帮助我们快速的写出符合 restful 规范的接口。
djangorestframework 3.6.4 (python2.7 django1.11.5)
- Python (2.7, 3.2, 3.3, 3.4, 3.5, 3.6) # drf <= 3.8 support python2.7
- Django (1.8, 1.9, 1.10, 1.11)
djangorestframework 3.10.0
- Python (3.5, 3.6, 3.7) # drf >= 3.9 support python3.7
- Django (1.11, 2.0, 2.1, 2.2)
djangorestframework 3.11.2 (python3.7 django1.11.17 drf3.11.2)
- Python (3.5, 3.6, 3.7, 3.8)
- Django (1.11, 2.0, 2.1, 2.2, 3.0) # the last version which support django 1.11
djangorestframework 3.12(latest version 3.12.4 2021-03)
- Python (3.5, 3.6, 3.7, 3.8, 3.9)
- Django (2.2, 3.0, 3.1) # django >= 2.0
models.py
from django.db import models
# Create your models here.
class MyBook(models.Model):
title = models.CharField(max_length=32)
price = models.IntegerField()
view.py
from rest_framework.viewsets import ModelViewSet
from .serializer import BookSerializer
from app01 import models
class BookView(ModelViewSet):
queryset = models.MyBook.objects.all()
serializer_class = BookSerializer
serializer.py
from rest_framework import serializers
from .models import MyBook
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = MyBook
fields = '__all__'
urls.py
from django.contrib import admin
from django.urls import path, re_path
from app01 import views
from rest_framework.routers import SimpleRouter
router = SimpleRouter()
router.register('books', views.BookView, 'books')
urlpatterns = [
re_path('admin/', admin.site.urls),
]
urlpatterns += router.urls