异常处理与自动生成文档

“圣人千虑,必有一失”,程序也是如此。当 RESTful Web API 服务器发生异常,该如何处理呢?构建好的 RESTful Web API,客户端开发人员又该如何调用呢?这一节,我们就为大家一一道来。

1.异常处理

当遇到异常时,Django Rest framework 会自动捕获,并按默认逻辑处理。我们也可以通过自定义异常处理函数来实现对异常的处理。

from rest_framework.views import exception_handler

def custom_exception_handler(exc, context):
    # 先调用REST framework默认的异常处理方法获得标准错误响应对象
    response = exception_handler(exc, context)

    # 在此处补充自定义的异常处理
    if response is not None:
        response.data['status_code'] = response.status_code

    return response

在配置文件中声明自定义的异常处理

REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler'
}

如果未声明,会采用默认的方式,如下

REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler'
}

例如:

补充上处理关于数据库的异常

from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework import status
from django.db import DatabaseError

def exception_handler(exc, context):
    response = drf_exception_handler(exc, context)

    if response is None:
        view = context['view']
        if isinstance(exc, DatabaseError):
            print('[%s]: %s' % (view, exc))
            response = Response({'detail': '服务器内部错误'}, status=status.HTTP_507_INSUFFICIENT_STORAGE)

    return response

2.REST framework 提供的异常类

  • APIException 所有异常的父类;

  • ParseError 解析错误;

  • AuthenticationFailed 认证失败;

  • NotAuthenticated 尚未认证;

  • PermissionDenied 权限决绝;

  • NotFound 未找到;

  • MethodNotAllowed 请求方式不支持;

  • NotAcceptable 要获取的数据格式不支持;

  • Throttled 超过限流次数;

  • ValidationError 校验失败。

3.自动生成接口文档

在前后端分离的项目中,在完成接口的开发之后,后端开发人员需要为前端人员编写接口文档,介绍接口调用方法和需要传递的参数。在 Django Rest framework 编写接口后,可以自动生成接口文档,这无疑减轻了不少工作量。

接口文档以网页的方式呈现,在生产接口文档前,需要做如下操作:

3.1 安装依赖

Django Rest framework 自动生成接口文档,需要coreapi库的支持,在终端输入如下命令:

pip install coreapi

3.2 在设置文件中进行配置

REST_FRAMEWORK = {
    'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.AutoSchema'
}

3.3 配置接口文档访路由地址

在总路由中添加接口文档路径。

文档路由对应的视图配置为rest_framework.documentation.include_docs_urls

参数title为接口文档网站的标题。

from rest_framework.documentation import include_docs_urls

urlpatterns = [
    ...
    path('docs/', include_docs_urls(title='接口文档'))
]

4. 文档描述说明的定义位置

  1. 单一方法的视图,可直接使用类视图的文档字符串,如:
class StudentView(generics.ListAPIView):
    """
    返回所有学生信息.
    """
  1. 包含多个方法的视图,在类视图的文档字符串中,分开方法定义,如:
class StudentListCreateView(generics.ListCreateAPIView):
    """
    get:
    返回所有学生信息.

    post:
    新建学生信息.
    """
  1. 对于视图集 ViewSet,仍在类视图的文档字符串中分开定义,但是应使用操作动作名称来区分,如:
class BookInfoViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
    """
    list:
    返回学生列表数据

    retrieve:
    返回学生详情数据

    latest:
    返回最新的学生数据
    """

5. 访问接口文档网页

注意:

  1. 视图集 ViewSet 中的 retrieve 方法,在接口文档中被称作 read;

  2. 参数的 Description 需要在模型类或序列化器类的字段中以 help_text 选项定义,如:

class StudentsModel(models.Model):
    ...
    s_name = models.CharField(max_length=8, verbose_name='学生姓名', help_text='学生姓名')
    ...

6.小结

本小节为大家介绍了 API 实现过程中异常处理和 API 文档的生成。熟练运用异常处理技巧,可以很大程度上避免程序出错,保证稳定运行。API 文档的生成功能,可以快速生成 API 使用手册,而无需另外书写,这让广大程序员摆脱了写文档的烦恼。