前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >测试开发进阶(二十四)

测试开发进阶(二十四)

作者头像
zx钟
发布2019-10-15 15:28:53
1.1K0
发布2019-10-15 15:28:53
举报
文章被收录于专栏:测试游记

REST API

官方文档:https://restfulapi.net/

一种开发理念「是设计风格 而不是标准」

REST is acronym for REpresentational State Transfer.

每一个URL代表一种「资源

具体要对资源做什么操作,要体现在请求方式上,而不是URL上

  • json格式数据
  • text文本
  • 图片,视频等

客户端和服务器之间,传递这种资源的某种表现形式

  • 通过请求头中的 Content-Type来指明传给服务端的参数类型

text/plain application/xml text/html application/json image/gif image/jpeg Application/x-www-form-urlencoded

  • 通过请求头中 Accept来指明希望接受服务端的数据类型

Accept:application/json,application/xml;q=0.9,*/*;q=0.8

  • POST:创建「create」
  • GET:获取「read」
  • PUT:更新,替换「update/replace」
  • PATCH:部分更新「Partial update/modify」
  • DELETE:删除「delete」

设计规则

命名
  • 尽量使用名词复数形式
  • 往往与数据库的表名对应
过滤条件

一般记录数量较多,服务器不可能将所有数据都返回给前端

例如:

代码语言:javascript
复制
?page=2&size=10 指定页数,条数
?sort=name         指定排序
域名

尽量使用专用域名

前后端分离之后,前后端都有一个域名

例如 http://api.xxx.xxx

版本
  • 在url中呈现版本号
代码语言:javascript
复制
http://api.xxx.xxx/app/0.1
  • 在请求头中呈现
代码语言:javascript
复制
Accept: application/vnd.example.v0.2+json
Accept: application/vnd.example+json;version=1.1
常见请求含义
  • GET(SELECT):从服务器获取资源(一项或多项)
  • POST(CREATE):从服务器新建一个资源
  • PUT(UPDATE):从服务器更新资源(客户端提供改变后的完整资源)
  • DELETE(DELETE):从服务器删除资源
  • PATCH(UPDATE WHERE):在服务器部分更新资源(客户端提供改变的属性)
  • HEAD:获取资源的元数据
  • OPTIONS:获取关于资源的哪些属性是客户端可以改变的信息
状态码
  • 200:OK

「GET」服务器成功返回用户请求的数据

  • 201:CREATED

「POST/PUT/PATCH」用户新建或修改数据成功

  • 204:NO CONTENT

「DELETE」用户删除数据成功

  • 400:INVALID REQUEST

「POST/PUT/PATCH」用户请求有误(请求参数有误)

  • 401:Unauthorized

「*」用户没有权限(令牌,用户名,密码错误)

  • 403:Forbidden

「*」表示用户得到授权(与401错误相对),但是访问是被禁止的

  • 404:NOT FOUND

「*」用户请求路径不存在

  • 500:INTERNAL SERVER ERROR

「*」服务器发生错误

接口设计

最原始设计

GET
  1. 从数据库中获取所有的项目信息
  2. 将数据库模型实例转化为字典类型「Json数组」「嵌套字典的列表」
  3. 注意:JsonResponse第一个参数默认只能为dict字典,如果要设为其他类型,需要将safe设为False
代码语言:javascript
复制
# LearnDjango/projects/views.py
from django.http import JsonResponse
from projects.models import Projects
from django.views import View


class ProjectsList(View):
    def get(self, reuqest):
        # 1.从数据库中获取所有的项目信息
        project_qs = Projects.objects.all()
        # 2.将数据库模型实例转化为字典类型「Json数组」「嵌套字典的列表」
        project_list = []
        for project in project_qs:
            project_list.append(
                {
                    'name': project.name,
                    'leader': project.leader,
                    'tester': project.tester,
                    'programer': project.programer,
                    'publish_app': project.publish_app,
                    'desc': project.desc
                }
            )
        # JsonResponse第一个参数默认只能为dict字典,如果要设为其他类型,需要将safe设为False
        return JsonResponse(project_list, safe=False)
代码语言:javascript
复制
# LearnDjango/projects/urls.py
from django.urls import path
from projects import views

urlpatterns = [
    path('project/', views.ProjectsList.as_view()),
]


# LearnDjango/urls.py
from django.contrib import admin
from django.urls import path, include, re_path

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('projects.urls'))
]
代码语言:javascript
复制
$ http http://127.0.0.1:8000/project/
zhongxindeMacBook-Pro:~ zhongxin$ http http://127.0.0.1:8000/project/
HTTP/1.1 200 OK
Content-Length: 650
Content-Type: application/json
Date: Fri, 11 Oct 2019 13:02:56 GMT
Server: WSGIServer/0.2 CPython/3.7.1
Vary: Origin
X-Frame-Options: SAMEORIGIN

[
    {
        "desc": "666",
        "leader": "zx_94",
        "name": "测试游记",
        "programer": "zhong",
        "publish_app": "公众号",
        "tester": "zx"
    },
    {
        "desc": "6666",
        "leader": "zx_94_1",
        "name": "测试游记1",
        "programer": "zhong1",
        "publish_app": "公众号1",
        "tester": "zx1"
    },
    {
        "desc": "666",
        "leader": "zx_94",
        "name": "「测试游记」-创建",
        "programer": "zx",
        "publish_app": "公众号",
        "tester": "zx"
    },
    {
        "desc": "666",
        "leader": "钟鑫",
        "name": "10月1日作业",
        "programer": "钟鑫",
        "publish_app": "国庆作业",
        "tester": "钟鑫"
    }
]
POST
  1. 从前端获取json格式的数据,转化为Python中的类型

为了严谨性,这里需要做各种复杂的校验 比如:是否为json,传递的项目数据是否符合要求,有些必传参数是否携带

  1. 向数据库中新增项目
  2. 将模型类转化为字典,然后返回
代码语言:javascript
复制
def post(self, request):
    """
    新建项目
    """
    # 1.从前端获取json格式的数据,转化为Python中的类型
    # 为了严谨性,这里需要做各种复杂的校验
    # 比如:是否为json,传递的项目数据是否符合要求,有些必传参数是否携带
    json_data = request.body.decode('utf8')
    python_data = json.loads(json_data, encoding='utf8')
    # 2.向数据库中新增项目
    project = Projects.objects.create(**python_data)
    # 3.将模型类转化为字典,然后返回
    one_dict = {
        'name': project.name,
        'leader': project.leader,
        'tester': project.tester,
        'programer': project.programer,
        'publish_app': project.publish_app,
        'desc': project.desc
    }
    return JsonResponse(one_dict)
代码语言:javascript
复制
$ http POST http://127.0.0.1:8000/project/ name=10月11日「测试游记」 leader=zx tester=zx programer=zx publish_app=10月11日内容 desc=测试post请求
zhongxindeMacBook-Pro:~ zhongxin$ http POST http://127.0.0.1:8000/project/ name=10月11日「测试游记」 leader=zx tester=zx programer=zx publish_app=10月11日内容 desc=测试post请求
HTTP/1.1 200 OK
Content-Length: 202
Content-Type: application/json
Date: Fri, 11 Oct 2019 13:31:46 GMT
Server: WSGIServer/0.2 CPython/3.7.1
Vary: Origin
X-Frame-Options: SAMEORIGIN

{
    "desc": "测试post请求",
    "leader": "zx",
    "name": "10月11日「测试游记」",
    "programer": "zx",
    "publish_app": "10月11日内容",
    "tester": "zx"
}
GET具体内容
  1. 校验前端传递的pk(项目ID)值,类型是否正确(正整数),在数据库中是否存在等「先省略」
  2. 获取指定pk值的项目
  3. 将模型类转化为字典,然后返回
代码语言:javascript
复制
# projects/views.py
class ProjectDetail(View):
    def get(self, request, pk):
        # 1.校验前端传递的pk(项目ID)值,类型是否正确(正整数),在数据库中是否存在等「先省略」
        # 2.获取指定pk值的项目
        project = Projects.objects.get(id=pk)
        # 3.将模型类转化为字典,然后返回
        one_dict = {
            'name': project.name,
            'leader': project.leader,
            'tester': project.tester,
            'programer': project.programer,
            'publish_app': project.publish_app,
            'desc': project.desc
        }
        return JsonResponse(one_dict)
代码语言:javascript
复制
# projects/urls.py
from django.urls import path
from projects import views

urlpatterns = [
    path('project/', views.ProjectsList.as_view()),
    path('project/<int:pk>/', views.ProjectDetail.as_view()),
]
代码语言:javascript
复制
$ http :8000/project/1/
zhongxindeMacBook-Pro:~ zhongxin$ http :8000/project/1/
HTTP/1.1 200 OK
Content-Length: 145
Content-Type: application/json
Date: Fri, 11 Oct 2019 13:42:44 GMT
Server: WSGIServer/0.2 CPython/3.7.1
Vary: Origin
X-Frame-Options: SAMEORIGIN

{
    "desc": "666",
    "leader": "zx_94",
    "name": "测试游记",
    "programer": "zhong",
    "publish_app": "公众号",
    "tester": "zx"
}
PUT具体内容
  1. 校验前端传递的pk(项目ID)值,类型是否正确(正整数),在数据库中是否存在等「先省略」
  2. 获取指定pk值的项目
  3. 从前端获取json格式的数据,转化为Python中的类型

为了严谨性,这里需要做各种复杂的校验 比如:是否为json,传递的项目数据是否符合要求,有些必传参数是否携带

  1. 更新项目
  2. 将模型类转化为字典,然后返回
代码语言:javascript
复制
def put(self, request, pk):
    # 1.校验前端传递的pk(项目ID)值,类型是否正确(正整数),在数据库中是否存在等「先省略」
    # 2.获取指定pk值的项目
    project = Projects.objects.get(id=pk)
    # 3.从前端获取json格式的数据,转化为Python中的类型
    # 为了严谨性,这里需要做各种复杂的校验
    # 比如:是否为json,传递的项目数据是否符合要求,有些必传参数是否携带
    json_data = request.body.decode('utf8')
    python_data = json.loads(json_data, encoding='utf8')
    # 4.更新项目
    project.name = python_data['name']
    project.leader = python_data['leader']
    project.tester = python_data['tester']
    project.programer = python_data['programer']
    project.publish_app = python_data['publish_app']
    project.desc = python_data['desc']
    project.save()
    # 5.将模型类转化为字典,然后返回
    one_dict = {
        'name': project.name,
        'leader': project.leader,
        'tester': project.tester,
        'programer': project.programer,
        'publish_app': project.publish_app,
        'desc': project.desc
    }
    return JsonResponse(one_dict, status=201)
代码语言:javascript
复制
$ http PUT :8000/project/5/ name=10月11日「测试游记」 leader=zhongxin tester=zx programer=zx publish_app=10月11日内容 desc=测试post请求
zhongxindeMacBook-Pro:~ zhongxin$ http PUT :8000/project/5/ name=10月11日「测试游记」 leader=zhongxin tester=zx programer=zx publish_app=10月11日内容 desc=测试post请求
HTTP/1.1 201 Created
Content-Length: 208
Content-Type: application/json
Date: Fri, 11 Oct 2019 13:53:49 GMT
Server: WSGIServer/0.2 CPython/3.7.1
Vary: Origin
X-Frame-Options: SAMEORIGIN

{
    "desc": "测试post请求",
    "leader": "zhongxin",
    "name": "10月11日「测试游记」",
    "programer": "zx",
    "publish_app": "10月11日内容",
    "tester": "zx"
}
DELETE
  1. 校验前端传递的pk(项目ID)值,类型是否正确(正整数),在数据库中是否存在等「先省略」
  2. 获取指定pk值的项目
  3. 删除
代码语言:javascript
复制
def delete(self, request, pk):
    # 1.校验前端传递的pk(项目ID)值,类型是否正确(正整数),在数据库中是否存在等「先省略」
    # 2.获取指定pk值的项目
    project = Projects.objects.get(id=pk)
    project.delete()
    return JsonResponse({}, safe=True, status=204)
代码语言:javascript
复制
$ http DELETE :8000/project/6/
zhongxindeMacBook-Pro:~ zhongxin$ http DELETE :8000/project/6/
HTTP/1.1 204 No Content
Content-Length: 2
Content-Type: application/json
Date: Fri, 11 Oct 2019 14:03:45 GMT
Server: WSGIServer/0.2 CPython/3.7.1
Vary: Origin
X-Frame-Options: SAMEORIGIN

原始设计小结

创建接口的任务

  1. 校验用户数据
  2. 将请求的数据(如json格式)转换为模型类对象

反序列化

  • 将其他格式(json,xml等)转换为程序中的数据类型
  • 将json格式的字符串转换为Django中的模型类对象
  1. 操作数据库
  2. 将模型类对象转换为响应的数据(如json格式)

序列化

  • 将程序中的数据类型转换为其他格式(json,xml等)
  • 例如将Django中的模型类对象转换为json字符串

数据增删改查流程

校验请求参数 -> 反序列化 -> 保存数据 -> 将保存的对象序列化并返回

判断要删除的数据是否存在 -> 执行数据删除

判断要修改的数据是否存在 -> 校验请求参数 -> 反序列化 -> 保存数据 -> 将保存的数据序列号并返回

查询数据库 -> 将数据序列化并返回

原始设计代码

代码语言:javascript
复制
import json
from django.http import JsonResponse
from projects.models import Projects
from django.views import View


class ProjectsList(View):
    def get(self, reuqest):
        # 1.从数据库中获取所有的项目信息
        project_qs = Projects.objects.all()
        # 2.将数据库模型实例转化为字典类型「Json数组」「嵌套字典的列表」
        project_list = []
        for project in project_qs:
            project_list.append(
                {
                    'name': project.name,
                    'leader': project.leader,
                    'tester': project.tester,
                    'programer': project.programer,
                    'publish_app': project.publish_app,
                    'desc': project.desc
                }
            )
        # JsonResponse第一个参数默认只能为dict字典,如果要设为其他类型,需要将safe设为False
        return JsonResponse(project_list, safe=False)

    def post(self, request):
        """
        新建项目
        """
        # 1.从前端获取json格式的数据,转化为Python中的类型
        # 为了严谨性,这里需要做各种复杂的校验
        # 比如:是否为json,传递的项目数据是否符合要求,有些必传参数是否携带
        json_data = request.body.decode('utf8')
        python_data = json.loads(json_data, encoding='utf8')
        # 2.向数据库中新增项目
        project = Projects.objects.create(**python_data)
        # 3.将模型类转化为字典,然后返回
        one_dict = {
            'name': project.name,
            'leader': project.leader,
            'tester': project.tester,
            'programer': project.programer,
            'publish_app': project.publish_app,
            'desc': project.desc
        }
        return JsonResponse(one_dict)


class ProjectDetail(View):
    def get(self, request, pk):
        # 1.校验前端传递的pk(项目ID)值,类型是否正确(正整数),在数据库中是否存在等「先省略」
        # 2.获取指定pk值的项目
        project = Projects.objects.get(id=pk)
        # 3.将模型类转化为字典,然后返回
        one_dict = {
            'name': project.name,
            'leader': project.leader,
            'tester': project.tester,
            'programer': project.programer,
            'publish_app': project.publish_app,
            'desc': project.desc
        }
        return JsonResponse(one_dict)

    def put(self, request, pk):
        # 1.校验前端传递的pk(项目ID)值,类型是否正确(正整数),在数据库中是否存在等「先省略」
        # 2.获取指定pk值的项目
        project = Projects.objects.get(id=pk)
        # 3.从前端获取json格式的数据,转化为Python中的类型
        # 为了严谨性,这里需要做各种复杂的校验
        # 比如:是否为json,传递的项目数据是否符合要求,有些必传参数是否携带
        json_data = request.body.decode('utf8')
        python_data = json.loads(json_data, encoding='utf8')
        # 4.更新项目
        project.name = python_data['name']
        project.leader = python_data['leader']
        project.tester = python_data['tester']
        project.programer = python_data['programer']
        project.publish_app = python_data['publish_app']
        project.desc = python_data['desc']
        project.save()
        # 5.将模型类转化为字典,然后返回
        one_dict = {
            'name': project.name,
            'leader': project.leader,
            'tester': project.tester,
            'programer': project.programer,
            'publish_app': project.publish_app,
            'desc': project.desc
        }
        return JsonResponse(one_dict, status=201)

    def delete(self, request, pk):
        # 1.校验前端传递的pk(项目ID)值,类型是否正确(正整数),在数据库中是否存在等「先省略」
        # 2.获取指定pk值的项目
        project = Projects.objects.get(id=pk)
        project.delete()
        return JsonResponse({}, safe=True, status=204)
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 测试游记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • REST API
    • 设计规则
      • 接口设计
        • 最原始设计
        • 原始设计小结
        • 数据增删改查流程
        • 原始设计代码
    相关产品与服务
    文件存储
    文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档