vantui框架官方文档_让 API 自动生成文档

阅读本文大概需要 7.9 分钟。

程序员最苦恼的事情莫过于写文档。由于业务口径频繁变更,因此很多接口也会频繁变更,频繁变更导致文档的维护是一件相当费时的事情,当优先级更高的事情袭来,更新文档反到成了次要工作,久而久之,文档就算有,也不是最新的,有些接口,干脆文档也不写了,口口相传了事。

没有文档,对于新手或者工作交接,是一件非常麻烦的事情,也不利于程序的传承。

那么,有没有这样一种程序,根据 api 函数的规范注释,及 api 的功能自动生成 api 的文档呢?这样一来,改接口,只要注释完善下,api 文档就自动生成,文档时刻保持最新,岂不省事。网上搜索了下,还真有大神实现了这样的框架。不得不感慨,没有程序员实现不了的好功能,只有程序员想不到的好方法。

实际上,一些流行的 web 框架已经原生集成了自动生成 api 文档的功能。比如我最近学习的 django rest framework 框架就可以自动生成 api 文档,有了这个功能,领导再也不用担心没有接口文档了。

下面对官方给和样例程序及自定义的 api 来自动生成文档,暂时不考虑 api 的权限及有选择的生成 api 文档的功能,这些在深入学习之后,都不是难事。这些样例的作用在于快速展示如何自动生成 api 文档的功能,想深入了解的还是要看下框架的源代码。

先开发 api

请先仿照  django rest framework 官方的教程快速实现一个 api。https://www.django-rest-framework.org/tutorial/quickstart/

比如,我这里的 api 视图代码就是这样子的:

1、官方的 api

##官方apifrom django.contrib.auth.models import User, Groupfrom rest_framework import viewsetsfrom mail.serializers import UserSerializer, GroupSerializerclass UserViewSet(viewsets.ModelViewSet):"""
    API endpoint that allows users to be viewed or edited.
    """
    queryset = User.objects.all().order_by('-date_joined')
    serializer_class = UserSerializerclass GroupViewSet(viewsets.ModelViewSet):"""
    API endpoint that allows groups to be viewed or edited.
    """
    queryset = Group.objects.all()
    serializer_class = GroupSerializer

2、我自己写的一个发送邮件的 api ,代码如下:

# Create your views here.from rest_framework.views import APIViewfrom django.core.mail import send_mail, BadHeaderErrorfrom rest_framework.response import Responsefrom .get_parameter import get_parameter_dicimport logging
logger = logging.getLogger('django')##自定义apiclass SendMail(APIView):"""
    发送信息到指定人员邮箱
    """def post(self, request, format=None):"""
        post:
        发送信息到指定人员邮箱
        参数列表:
            from_email: 发件人邮箱
            to_email: 收件人,多个收件人请使用英文逗号分隔隔开
            subject: 邮件主题
            message: 邮件正文
        """# 获取请求方的 ip 地址
        print(request.data)
        ip = ""if 'HTTP_X_FORWARDED_FOR' in request.META:
            ip = request.META['HTTP_X_FORWARDED_FOR']else:
            ip = request.META['REMOTE_ADDR']
        params = get_parameter_dic(request)
        subject = params['subject']
        message = params['message']
        from_email = params.get('from_email', 'somenzz@163.com')
        to_email = params['to_email']
        return_data = {'code': 0, 'message': f'send email to {to_email} successful.'}if subject and message and to_email:try:
                to_email = to_email.split(',')  # 多个收件人以;分隔
                print("to_email", to_email, type(to_email))
                send_mail(subject, message, from_email, to_email)except BadHeaderError:
                return_data['code'] = 1
                return_data['message'] = 'Invalid header found.'else:# In reality we'd use a form class# to get proper validation errors.
            return_data['code'] = 2
            return_data['message'] = 'Make sure all fields are entered and valid.'
        logger.info(f"ip = {ip}, subject = {subject },message = {message }, from_email = {from_email }, to_email = {to_email }, return_data = {return_data }")return Response(return_data)

这里使用了 post 方法,在 post 请求的 body 里可以传输 4 个参数,分别是 subject 、message、from_email、to_email。其中 from_email 有默认值,是 somenzz@163.com,因此这个参数也可以省略。

这里分享下 django 框架获取参数的通用函数

django 框架获取参数有多种方式,如 get 请求中参数都会在 url 中传输,比如:http://xxx.com/api/?name=asdf&phone=13xxxx  这样。使用 request.query_params 中可以获取 name,phone 等参数,request.query_params 返回的数据类型为 QueryDict,QueryDict 转为普通 python 字典 query_params.dict()即可。

在 post 请求参数一般放在请求的 body 中, 但是仍可以放在 url 仍中,类似 get 的形式, 最终结果, 参数会有两部分组成, 一部分在 url 中, 一部分在http body 中, 但是非常不建议这样做。接下来的代码编写也不会考虑这样的情况, post 仅考虑所有参数都在 http body 中的情况。这样,无论是 post ,还是 get ,我们可以编写统一的 参数获取函数,如下所示:

from django.http import QueryDictfrom rest_framework.request import Requestdef get_parameter_dic(request, *args, **kwargs):if isinstance(request, Request) == False:return {}
    query_params = request.query_paramsif isinstance(query_params, QueryDict):
        query_params = query_params.dict()
    result_data = request.dataif isinstance(result_data, QueryDict):
        result_data = result_data.dict()if query_params != {}:return query_paramselse:return result_data

也是自定义 api 中

from .get_parameter import get_parameter_dic

使用的函数。

3、修改 settings.py
在 INSTALLED_APPS  增加两项:

INSTALLED_APPS = ['mail.apps.MailConfig', #自定义的 app'rest_framework', #导入 rest_framework
]

修改时区:

TIME_ZONE = 'Asia/Shanghai'

增加发邮件的信息

EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.163.com'
EMAIL_PORT = 25
EMAIL_HOST_USER = 'somezz@163.com'
EMAIL_HOST_PASSWORD = '******'
EMAIL_USE_LOCALTIME = Tru

方法一、使用原生样式自动生成 api 文档

修改项目总的 urls.py,加入文档 url 路由,如下所示:

from django.contrib import adminfrom django.urls import path,includefrom rest_framework.documentation import include_docs_urlsfrom rest_framework import routersfrom mail import views
router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'groups', views.GroupViewSet)# Create our schema's view w/ the get_schema_view() helper method. Pass in the proper Renderers for swagger
urlpatterns = [
    path('admin/', admin.site.urls),
    path('mail/',include('mail.urls')),
    path('',include(router.urls)),
    path('api-docs/', include_docs_urls(title="api接口文档")),
]

与原本的 urls.py 相比,其实就多了两行代码,

from rest_framework.documentation import include_docs_urls
path('api-docs/', include_docs_urls(title="api接口文档")),

就是这两行代码,自动生成了 api 的文档。下面来看一下效果

0239c7554f0de70e0ea763862d073919.png

api1.png

我们可以看到这个 api 接口文档已经相当丰富了,左侧是所有的 api 列表,点击可以定位到相应的说明,也可以与点击 Source Code 查看多种语言调用 api 的样例代码。也可以点击 interact 按钮与 api 进行交互来测试  api,如下图所示:

5f66e41a1bcb322baafe3d912f69a154.png

api2.png

e3685b67fba39f687ae90cdb975e9d9d.png

api3.png

fc2f960e2ad60c03f2a2395d34151362.png

api33.png

也可以在侧查看返回信息,及原始字符串 raw。这些 api 有个共同点就是使用 django rest framework 封装好的类来实现的,屏蔽了很多细节,现在我们看一下自定义的发邮件 api,看看它的交互如何?

d4ad578344cb73009525b1ea466cc1df.png

自定义的api

可以看到它获取到了 api 中的注释字符串。

86f6e4d0704f1a7a8f2c35367261eb5c.png

自定义的api 未发现参数框

我们发现自定义的 api 没有对应的参数可以填写,这真让人郁闷。仔细啃官方的英文文档,终于在第二天实现了,方法如下:
修改自定义的 api 视图类,加入以下代码:

    schema = AutoSchema(manual_fields= [
        coreapi.Field(name="subject", required=True, location="query", description="邮件主题"),
        coreapi.Field(name="message", required=True, location="query", description="邮件正文"),
        coreapi.Field(name="from_email", required=False, location="query", description="发件人"),
        coreapi.Field(name="to_email", required=True, location="query", description="收件人,多个使用逗号分隔"),
    ])

前提要导入以下包:

from rest_framework.schemas import AutoSchemaimport coreapi

再次查看自定义的 api,发现有变化了:

38343223ad8c0dc27425d408f696216f.png

自定义的api

我们发现,有了参数,但是描述信息不知道为什么没有获取到,如果有大神知道,请赐教。

下面交互,

ca773ca091d9b514c2f5fd2e88151370.png

自定义的api交互成功

终于大功告成,后面有人来问 api 的事情,不用理他,向他扔这样一个 api 文档就可以了。

注意,这里依赖 coreapi ,使用过程中使用 pip 安装下即可

pip install coreapi 

方法二、使用第三方库自动生成 api 文档

这里介绍下 django-rest-swagger,使用方法如下:
1、先安装:

pip install django-rest-swagger

2、加入到 INSTALLED_APPS

    INSTALLED_APPS = (
        ...'rest_framework_swagger',
    )

3、修改项目 urls.py,类似下面这样:

from django.conf.urls import urlfrom rest_framework_swagger.views import get_swagger_view
schema_view = get_swagger_view(title='API 接口文档')
urlpatterns = [
    url(r'^docs$', schema_view)
]

本例中的效果如下所示:

0f21e6a894adac7194d39d86465d8092.png

rest_framework_swagger

9f998327966ce7b4dcfe1c4f9ecd436b.png

rest_framework_swagger

a74748e5695a31a628cb547dc5e1fdfa.png

交互

d81066bf4c571734f2ee9f7cfab8bda2.png

交互

功能和原生的大同小异,多了 curl 访问接口的方式,每个人喜欢的风格不一样,网上还有很多生成 api 文档的轮子,大家可以选一款自己喜欢的直接用就好。

完整代码已上传至百度云,微信公众号 somenzz 回复「api」获取下载链接,欢迎一起学习交流。

5125779401bb0f4b726d2cc5d11ab823.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值