HTTP 响应头 Deprecation 字段在 API 版本迭代的应用

API 版本迭代过程中,我们希望使用者能保持使用新版本 API,并且知道他正在使用的旧版本 API 即将废弃。维护者与使用者关于这点的沟通通常通过下面的方式:

  1. 维护者定期更新网站中 API 版本信息,使用者定期关注
  2. 维护者通过邮件主动通知使用者

这两种方式并不可靠,如果双方开发人员可以在程序交互时就交流这个信息,会比依赖人的通知更为准时可靠。

目前社区打算引进一个新的 HTTP 响应头字段 Deprecation 来传递这个信息

字段的格式:Deprecation: 1688169599

应用案例

原始版本

下面的案例中存在两个版本,使用者使用的是旧版本的接口,版本的信息交互只能通过响应体中的 [Version 1] 来传递(实际应用中可能在 json 响应字段中或者其他地方),这种方式的问题在于它不具备普适性,每个外部依赖的 API 关于版本废弃的信息格式和位置都不一样,很难做基础开发。

python 复制代码
from flask import Flask

app = Flask(__name__)

@app.route("/v1/list_books")
def get_book_list():
    return "This is a book list! [Version 1]"

@app.route("/v2/list_books")
def get_book_list_v2():
    return "This is a book list! [Version 2]"
shell 复制代码
➜  ~ curl -i http://172.21.208.1:5000/v1/list_books
HTTP/1.1 200 OK
Server: Werkzeug/3.0.6 Python/3.11.9
Date: Mon, 18 Nov 2024 07:04:25 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 20
Connection: close

This is a book list!%

使用 Deprecated 字段版本

python 复制代码
from datetime import datetime

from flask import Flask, make_response

app = Flask(__name__)

@app.route("/v1/list_books")
def get_book_list():
    resp = make_response("This is a book list!")
    deprecation_date = int(datetime(2024,11,20,23,59,59).timestamp())
    resp.headers["Deprecation"] = deprecation_date
    return resp

@app.route("/v2/list_books")
def get_book_list_v2():
    return "This is a book list! [Vesion 2]"
复制代码
➜  ~ curl -i http://172.21.208.1:5000/v1/list_books
HTTP/1.1 200 OK
Server: Werkzeug/3.0.6 Python/3.11.9
Date: Mon, 18 Nov 2024 08:36:03 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 20
Deprecation: 1732118399
Connection: close

这个版本只是增加了一个头字段,但对于API使用者来说可以做的发挥就增加了。

由于字段与时间表示方式遵循协议制定的格式,使用者可以做统一的开发,在响应头提取到 Deprecation 字段后:

  1. 使用者的系统对外部调用的API 统一监测响应头中的 Deprecation 字段,发出提示和告警,对于已经到达时间阈值内的发出告警
  2. 项目的请求中间件可以据此发出警告日志,从而使得在开发时得到提醒

下面我对这种应用做下基本演示:

python 复制代码
# 客户端代码
import logging
import time
from datetime import timedelta

import requests

logger = logging.Logger("Detect")


def api_response_hook(func):
    def new_func():
        resp = func()
        deprecation = resp.headers.get("Deprecation")
        if deprecation:
        	# 对 deprecation 提取到的时间值做计算,开发者可以清楚感知到还剩几天过期
            seconds = int(deprecation) - int(time.time())
            remain_days = timedelta(seconds=seconds).days
            logger.warning(f"Warning:{resp.request.url} will be deprecate after {remain_days} days!")
        return resp

    return new_func

@api_response_hook
def list_books():
    resp = requests.get("http://127.0.0.1:5000/v1/list_books")
    return resp

def main():
    resp = list_books()
    print(resp.text)


if __name__ == "__main__":
    main()
复制代码
Warning:http://127.0.0.1:5000/v1/list_books will be deprecate after 2 days!
This is a book list!
相关推荐
weixin_4166679620 分钟前
银河麒麟V10看门狗试验-1
网络·chrome·python
白帽攻防录31 分钟前
SRC 挖洞:WSO2 JWT 算法混淆绕过深度复盘,CVE-2026-5430 不支持的算法怎么变成管理员
网络·算法·安全·网络安全·jwt
starzy199038 分钟前
Flink 优化之网络缓存优化及参数详解:从数据传输机制到反压原理的生产调优指南
网络·缓存·flink
正经教主1 小时前
【FDE系列】阶段3:Day 58:Prompt 安全 — 注入、越狱与防护
网络·人工智能·安全·prompt·fde
实点科技3 小时前
实点科技IO-Link I/O IOL7A/B系列参数配置方法介绍
网络
JVM高并发3 小时前
使用 Cloudflare Tunnel(本地管理隧道)搭配 DigitalPlat 免费域名实现内网穿透
网络协议·全栈
吴声子夜歌3 小时前
Nginx应用与运维——Nginx HTTP模块详解(动态赋值功能模块)
运维·nginx·http
Zelman3 小时前
网络协议性能调优手册
网络协议·性能优化
Zelman3 小时前
TCP-IP 协议栈设计哲学
网络协议
梦帮科技4 小时前
LoRA / QLoRA 低秩矩阵流形更新:SVD 分解、秩与缩放因子 α 的物理意义与梯度稳定性保障
网络·深度学习·神经网络·线性代数·矩阵·架构·数据挖掘