基于Python的API接口配置化写法设计讨论

现在市面上的开源框架, 不管是 tornado, django 或者 flask. 写起 API 总感觉没有 Nodejs 中的 hapijs 框架爽, 根据 hapijs 的设计原理, 我设想了下面的写法. 大家一起来讨论. 基于配置的方法去写接口感觉真的很舒适. 部分代码如下. (框架还没有, 只是设想. )

app.js

from api import *
from .apis.post import post
from .apis.user import user
from .plugins.my_plugin import MyPlugin

app = App()

app.plugin(MyPlugin) app.plugin(AuthorizationPlugin(‘jwt’))

app.publish(user) app.publish(post)

app.start(port=3000)

user.js

from api import *
from .services.user import UserService

user = BluePrint() user.role(‘admin’)

@user.cache({ ‘expires_in’: 30 * 1000, ‘privacy’: ‘private’ }) @user.query({ ‘name’: Field().string() }) @user.role(‘all’) @user.get(’/’) def list(self, request): users = UserService.list(**request.query) return Response(users)

@user.cache({ ‘expires_in’: 30 * 1000, ‘privacy’: ‘private’ }) @user.params({ ‘id’: Field().string() }) @user.role(‘login_user’) @user.get(’/{id}’) def retrieve(self, request): user = UserService.retrieve(id=request.params[id]) return Response(user)

@user.payload({ ‘name’: Field().string() }) @user.role(‘admin’) @user.post(’/’) def create(self, request): user = UserService.create(request.payload) return Response(user)

@user.payload({ ‘name’: Field().string() }) @user.params({ ‘id’: Field().string() }) @user.role(‘admin’) @user.patch(’/{id}’) def update(self, request): user = UserService.update(id=request.params[id], payload=request.payload) return Response(user)

@user.payload({ ‘name’: Field().string() }) @user.params({ ‘id’: Field().string() }) @user.role(‘admin’) @user.put(’/{id}/name’) def replace_name(self, request): user = UserService.update(id=request.params[id], payload=request.payload) return Response(user)


基于Python的API接口配置化写法设计讨论

9 回复

Flask 稍微封装一下也可以写出这种效果,待我回去截个图


对于API接口的配置化写法,核心思路是把路由、参数校验、业务逻辑解耦。我常用Pydantic做数据校验,FastAPI做框架,再用一个YAML或JSON配置文件定义接口结构。

比如,先定义一个配置模型:

from pydantic import BaseModel
from typing import Dict, Any

class EndpointConfig(BaseModel):
    path: str
    method: str
    request_model: Dict[str, Any]
    handler: str  # 指向实际处理函数的导入路径

然后在配置文件里这么写:

endpoints:
  - path: "/users"
    method: "GET"
    request_model:
      name: "string"
      age: "integer"
    handler: "app.handlers.get_users"

最后用个加载器动态注册路由:

import importlib
from fastapi import FastAPI

app = FastAPI()

def register_endpoints(config_path: str):
    configs = load_config(config_path)  # 加载YAML/JSON
    for cfg in configs["endpoints"]:
        handler_module, handler_name = cfg["handler"].rsplit(".", 1)
        module = importlib.import_module(handler_module)
        handler_func = getattr(module, handler_name)
        
        # 动态创建Pydantic模型
        RequestModel = create_pydantic_model(cfg["request_model"])
        
        # 注册路由
        app.add_api_route(
            cfg["path"],
            handler_func,
            methods=[cfg["method"]],
            response_model=...  # 根据需要配置
        )

这样改接口只需要改配置文件,不用动代码。不过要注意类型安全和错误处理,特别是动态导入那块。

总结:配置化能提升开发效率,但要处理好类型安全和错误处理。

~~ 看不懂,也没个注释 讲解,进来一脸懵逼

API 写法

Flask 封装




这样写还是比较方便的,不过不建议造新框架,生态很重要

doc_view 里面我用模板生成了 .apib (API Blueprint https://apiblueprint.org/) 格式的文档。
这些代码没从项目里抽取出来,要做成通用的框架或插件要考虑很多使用场景的问题。我这里约定 全部 POST,全部 JSON,所以省了很多事。

文档效果

flask-restful 自带函数验证

你指的是 RequestParser 吗,感觉有点繁琐,另外它不方便生成文档

回到顶部