[flask]统一API响应格式

flask,api · 浏览次数 : 2

小编点评

前言: 在设计API返回内容时,为了方便前端进行数据反序列化、处理以及其他服务调用,需要与前端约定好API返回的响应体格式。本篇文档将以JSON响应体为例,讲解如何定义一个符合规范的API响应类,并给出一个简单的客户端请求测试。 一、响应体格式规范 一个典型的JSON响应体包含以下几个部分: 1. code字段:表示错误类型和状态码,如HTTP状态码或自定义状态码。 2. msg字段:对当前code状态码的错误明细进行补充说明,通常不同的code状态码会有不同的message描述信息。 3. data字段:代表返回的响应体内容。 二、JSON响应类定义 以下代码定义了一个JSON响应类,用于表示一个JSON响应: ```python class JsonResponse: def __init__(self, code: HTTPStatus = HTTPStatus.OK, msg: str = "success", data=None): self.code = code self.msg = msg self.data = data def to_dict(self): return { "code": self.code.value, "msg": self.msg, "data": self.data, } def to_json(self): return jsonify(self.to_dict()) def response(self): response = make_response(self.to_json(), self.code.value) response.headers["Content-Type"] = "application/json" return response ``` 三、异常处理 对于404和一般异常,我们可以通过定义错误处理器来统一处理。以下是两个异常处理函数的示例代码: ```python @app.errorhandler(404) def error_handler_not_found(error): req_method = request.method req_path = request.path return JsonResponse( code=HTTPStatus.NOT_FOUND, msg=f"{req_method} {req_path} Not Found", ).response() @app.errorhandler(Exception) def error_handler_generic(error): req_method = request.method req_path = request.path return JsonResponse( code=HTTPStatus.INTERNAL_SERVER_ERROR, msg=f"Internal Server Error. {req_method} {req_path}", data={"error": str(error)}, ).response() ``` 四、客户端请求测试 以下是一个简单的客户端请求测试,分别测试了正常响应、404错误和一般异常场景: ```sh $ curl -s http://127.0.0.1:8001/a/1 | python3 -m json.tool {"code": 200, "data": {"content": "this is /a/1"}, "msg": "success"} $ curl -s http://127.0.0.1:8001/a/2 | python3 -m json.tool {"code": 500, "data": {"error": "exception in a/2"}, "msg": "Internal Server Error. GET /a/2"} $ curl -s http://127.0.0.1:8001/a/3 | python3 -m json.tool {"code": 404, "data": null, "msg": "GET /a/3 Not Found"} ``` 综上所述,本篇文档详细介绍了API返回内容时的规范要求,包括响应体格式、JSON响应类定义以及异常处理。同时,通过一个简单的客户端请求测试,展示了如何使用这些规则进行实际操作。

正文

前言

在设计API返回内容时,通常需要与前端约定好API返回响应体内容的格式。这样方便前端进行数据反序列化时相应的解析处理,也方便其它服务调用。不同公司有不同的响应内容规范要求,这里以常见的JSON响应体为例:

{
    "code": 200,
    "data": {
        "content": "this is /a/1"
    },
    "msg": "success"
}

code字段

code状态码主要用于表示错误类型区间状态码。如果设计比较简单,可以直接使用HTTP的状态码。如果是一个大型系统,也可以设计一套自定义的状态码。比如:

from enum import Enum

class BizStatus(Enum):
    # custom status code
    OK = 200
    BadRequestA1 = 4001  # 请求参数异常-A情况
    BadRequestA2 = 4002  # 请求参数异常-B情况

message字段

message 字段是对当前 code 状态码错误明细的补充说明。通常不同的code状态码会有不同的message描述信息。

data字段

data 值通常代表返回的响应体内容。

示例代码

以下代码定义了一个JSON响应类,api在返回的时候需要引用这个响应类。除此之外,还对404和一般异常做了统一处理,当出现这两类异常时,也会返回JSON结构的响应体。

from flask import Flask, request, jsonify, make_response
from http import HTTPStatus

API_KEY_SVCA = "flask_unify_response"

app = Flask(__name__)


class JsonResponse:
    """A class to represent a JSON response."""
    def __init__(
        self, code: HTTPStatus = HTTPStatus.OK, msg: str = "success", data=None
    ):
        self.code = code
        self.msg = msg
        self.data = data

    def to_dict(self):
        return {
            "code": self.code.value,
            "msg": self.msg,
            "data": self.data,
        }

    def to_json(self):
        return jsonify(self.to_dict())

    def response(self):
        response = make_response(self.to_json(), self.code.value)
        response.headers["Content-Type"] = "application/json"
        return response


@app.errorhandler(404)
def error_handler_not_found(error):
    req_method = request.method
    req_path = request.path
    return JsonResponse(
        code=HTTPStatus.NOT_FOUND,
        msg=f"{req_method} {req_path} Not Found",
    ).response()


@app.errorhandler(Exception)
def error_handler_generic(error):
    req_method = request.method
    req_path = request.path
    return JsonResponse(
        code=HTTPStatus.INTERNAL_SERVER_ERROR,
        msg=f"Internal Server Error. {req_method} {req_path}",
        data={"error": str(error)},
    ).response()


@app.get("/a/1")
def apitest_a1():
    return JsonResponse(
        code=HTTPStatus.OK, msg="success", data={"content": "this is /a/1"}
    ).response()


@app.get("/a/2")
def apitest_a2():
    raise Exception("exception in a/2")


if __name__ == "__main__":
    app.run(host="127.0.0.1", port=8001)

客户端请求测试:

$ curl -s http://127.0.0.1:8001/a/1 | python3 -m json.tool
{
    "code": 200,
    "data": {
        "content": "this is /a/1"
    },
    "msg": "success"
}


$ curl -s http://127.0.0.1:8001/a/2 | python3 -m json.tool
{
    "code": 500,
    "data": {
        "error": "exception in a/2"
    },
    "msg": "Internal Server Error. GET /a/2"
}


$ curl -s http://127.0.0.1:8001/a/3 | python3 -m json.tool
{
    "code": 404,
    "data": null,
    "msg": "GET /a/3 Not Found"
}

与[flask]统一API响应格式相似的内容:

[flask]统一API响应格式

前言 在设计API返回内容时,通常需要与前端约定好API返回响应体内容的格式。这样方便前端进行数据反序列化时相应的解析处理,也方便其它服务调用。不同公司有不同的响应内容规范要求,这里以常见的JSON响应体为例: { "code": 200, "data": { "content": "this is

在 Flask 项目中配置 Session:简明指南

本文介绍如何在 Flask 项目中配置会话 1. Flask 内置会话 Flask 自带会话管理功能,使用客户端 Cookie 存储会话数据。默认情况下,会话数据是签名的,以防止篡改,但未加密。因此,不建议在会话中存储敏感信息。Flask 内置会话适用于小型应用或会话数据量较少的情况。此外,默认情况

轻量级Web框架Flask(二)

Flask-SQLAlchemy MySQL是免费开源软件,大家可以自行搜索其官网(https://www.MySQL.com/downloads/) 测试MySQL是否安装成功 在所有程序中,找到MySQL→MySQL Server 5.6下面的命令行工具,然后单击输入密码后回车,就可以知道MyS

Flask框架:运用Ajax轮询动态绘图

Ajax是异步JavaScript和XML可用于前后端交互,在之前`《Flask 框架:运用Ajax实现数据交互》`简单实现了前后端交互,本章将通过`Ajax`轮询获取后端的数据,前台使用`echart`绘图库进行图形的生成与展示,后台通过`render_template`方法返回一串JSON数据集,前台收到后将其应用到绘图库上,实现动态监控内存利用率的这个功能。

Flask框架:如何运用Ajax轮询动态绘图

摘要:Ajax是异步JavaScript和XML可用于前后端交互。 本文分享自华为云社区《Flask框架:运用Ajax轮询动态绘图》,作者:LyShark。 Ajax是异步JavaScript和XML可用于前后端交互,在之前《Flask 框架:运用Ajax实现数据交互》简单实现了前后端交互,本章将通

《Flask Web 开发指南 pt.1》

最近在看辉哥的《Flask Web 开发实战》,这才有了《Flask Web 开发指南》系列的文章,偏向学习笔记多一点,也有实战的内容 看下这个系列的文章我能写多少篇 :) 愚人节玩笑 愚人节大家都喜欢开玩笑来整蛊别人以便达到娱乐效果,但对于开发者来说,就有可能出现让人意想不到的情况 2010 年

《Flask Web 开发指南 pt.2》

哈喽大家好,我是咸鱼 在《Flask Web 开发指南 pt.1》中,咸鱼跟大家介绍了 Flask 的由来——诞生于一个愚人节玩笑,简单介绍了一些关于 Flask 的概念,并且编写了一个简单的 Flask 程序 在编写 Flask 程序的时候,你需要注意你的程序文件不要命名为 flask.py,建议

Flask 上下文是什么 ?

哈喽大家好,我是咸鱼。今天我们来聊聊什么是 Flask 上下文 咸鱼在刚接触到这个概念的时候脑子里蹦出的第一个词是 CPU 上下文 今天咸鱼希望通过这篇文章,让大家能够对 Flask 上下文设计的初衷以及应用有一个基本的了解 Flask 上下文 我们在使用 Flask 开发 web 程序的时候,通常

通过钩子函数+Traceid实现Flask链路追踪

背景 在flask web中我们通常需要一个traceid作为调用参数传递给全链路各个调用函数 需要针对一次请求创建一个唯一的traceid:这里用uuid去简化代替 我们需要保证traceid不被污染,在每个请求期间存在,在请求结束销毁且线程独立:这里通过flask中的g对象来存储线程内的数据 由

Python Flask - 快速构建Web应用详解

本文将详细探讨Python Flask Web服务。我将首先简单介绍Flask,然后将逐步进入Flask中的路由、模板、表单处理以及数据库集成等高级概念,目标是能够让大家了解并掌握使用Flask来创建动态Web应用的技巧。 ## 1. Flask简介 Flask是一个轻量级的Web服务器网关接口(W