API文档自动生成工具调研

API文档自动生成工具调研

项目背景

项目的版本为python2.7,django1.11,采用的前后端交互方式是人工手写接口文档,交给前端,人工写postman接口测试,没有一套高效的自动接口文档生成和自动化测试的流程。

调研过程

//依赖库
djangorestframework==3.9.4
coreapi==2.3.3
django-rest-swagger==2.2.0
drf-yasg

实现方式:Django Rest Swagger生成api文档

实现思路:

  1. 修改settings配置,添加依赖库,添加swagger配置
  2. 修改urls.py 添加swagger文档路由,添加视图路由
  3. 添加视图类
  4. 实现序列化类
  5. 实现模型类

djangorestframework


在这里插入图片描述

这种模式在postman就能实现,没必要再自己再重新造一套。

在这里插入图片描述

这种接口文档的形式,可以满足需求,但还是没有swagger优雅简洁。

在实现这种模式的时候也遇到不少坑,最终没有呈现出这个效果。

django-rest-swagger:deprecated (2019-06-04)

  • Django 1.8+
  • Django REST framework 3.5.1+
  • Python 2.7, 3.5, 3.6

在这里插入图片描述

核心库还是在coreapi,djangorestframework。

依赖于上述核心库的编码方式,换成了swagger的ui

非常容易实现。

drf-yasg

  • Django Rest Framework: 3.10, 3.11, 3.12
  • Django: 2.2, 3.0, 3.1
  • Python: 3.6, 3.7, 3.8, 3.9

特征:

  • 完全支持嵌套序列化器和模式
  • 响应模式和描述
  • 模型定义与代码生成工具兼容
  • 在规范生成过程中的所有点上的定制挂钩
  • JSON和YAML格式的规范
  • 捆绑了最新版本的swagger-ui和redoc,用于查看生成的文档
  • 架构视图是可立即缓存的
  • 生成的Swagger模式可以通过Swagger -spec-validator自动验证
  • 通过URLPathVersioning和NamespaceVersioning支持Django REST框架API版本化;目前不支持其他DRF或自定义版本方案

swagger模式
在这里插入图片描述

redoc模式

在这里插入图片描述

总结:提供了更加强大,更多的功能,以及在可视化ui上做得更好,本质上还是使用了djangorestframework的编码风格

问题:由于python2.7的Django Rest Framework最高只支持3.9版本,所以不兼容3.10+的要求。故可预测该方案不可行。

优缺点:

优点:

  • 更规范科学的开发模式,自动生成api文档,节约大量在文档上编辑以及测试耗费的时间。
  • 更直观的管理接口

缺点:

  • 跟原项目的编码风格有较大出入,比如序列化过程,原项目并没有。而是直接从urls到service调用数据库。难以在项目开发规范中推广。
  • 需要踩大量坑,由于原项目的python跟django版本较低,在刚尝试使用这种模式就遇到大量坑,很难预测之后会遇到什么坑。增加今后潜在的开发成本
  • 需要配置session,目前还没有将项目内的接口跑通,测试成本还在增加。
  • 代码侵入性较强,没办法简便的对已开发的接口进行改造,只能考虑后续加入的接口。

总结:

对于当前项目的python和django版本,当前查到的资料都脱离不开Django Rest Framework的编码风格,对于之前已经开发的接口难以引入,同事想要的是一款尽量只改变路由就能实现文档生成,而不是进行大量代码的侵入,所以并不能采用上述的库,当前探索先告一段落。

踩坑记录:

  1. django1的urls.py中不支持path,改为url格式(django2才支持path)
  2. django修改settings或修改requirement没必要将整个docker-compose重启,项目自动重启失败可以手动重启,也可以直接进docker上直接执行pip
  3. you cannot access body after reding from request’s data stream

一旦对序列化类修改post传入的字段时,就会出现这个问题,查阅资料是说django不能让中间件修改request的post,所以用request.data而不是用request.body 或者将body的值用变量存起来再进行操作。

4.实现GET路径传参、POST传参,需要重写schema_views.py

# -*- coding: utf-8 -*-

from rest_framework.permissions import AllowAny
from rest_framework.schemas import SchemaGenerator
from rest_framework.schemas.generators import LinkNode, insert_into
from rest_framework.renderers import *
from rest_framework_swagger import renderers
from rest_framework.response import Response
from rest_framework.views import APIView
# from rest_framework.schemas import SchemaGenerator

class MySchemaGenerator(SchemaGenerator):

    def get_links(self, request=None):
        # from rest_framework.schemas.generators import LinkNode,
        links = LinkNode()

        paths = []
        view_endpoints = []
        for path, method, callback in self.endpoints:
            view = self.create_view(callback, method, request)
            path = self.coerce_path(path, method, view)
            paths.append(path)
            view_endpoints.append((path, method, view))

        # Only generate the path prefix for paths that will be included
        if not paths:
            return None
        prefix = self.determine_path_prefix(paths)

        for path, method, view in view_endpoints:
            if not self.has_view_permissions(path, method, view):
                continue
            link = view.schema.get_link(path, method, base_url=self.url)
            # 添加下面这一行方便在views编写过程中自定义参数.
            link._fields += self.get_core_fields(view)

            subpath = path[len(prefix):]
            keys = self.get_keys(subpath, method, view)

            # from rest_framework.schemas.generators import LinkNode, insert_into
            insert_into(links, keys, link)

        return links

    # 从类中取出我们自定义的参数, 交给swagger 以生成接口文档.
    def get_core_fields(self, view):
        return getattr(view, 'coreapi_fields', ())

class SwaggerSchemaView(APIView):
    _ignore_model_permissions = True
    exclude_from_schema = True

    # from rest_framework.permissions import AllowAny
    permission_classes = [AllowAny]
    # from rest_framework_swagger import renderers
    # from rest_framework.renderers import *
    renderer_classes = [
        CoreJSONRenderer,
        renderers.OpenAPIRenderer,
        renderers.SwaggerUIRenderer
  ]

def get(self, request):
    generator = MySchemaGenerator(title='接口文档',
                                  description='''接口文档''')

    schema = generator.get_schema(request=request)

    # from rest_framework.response import Response
    return Response(schema)

post传参

schema = AutoSchema(
            manual_fields=[
                coreapi.Field(name='code', required=True, location='form', description='', type='string'),
            ]
        )

get请求

coreapi_fields=(
        DocParam("token"),
    )

5.“msg”: “‘CreateWhitelistGroupView’ object has no attribute ‘session’”,

需要配置swagger登录获取session

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值