千家信息网

Python Web开发: 教你如何解放路由管理

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,1. 痛点随着业务的飞速发展,API接口越来越多,路由管理文件从几十号变成几百上千行,且每次上新服务,需要在修改路由文件代码,带来一定的风险。2. 解决方案既然路由文件随着业务的扩展越来越庞大,那就去
千家信息网最后更新 2026年11月01日Python Web开发: 教你如何解放路由管理

1. 痛点

随着业务的飞速发展,API接口越来越多,路由管理文件从几十号变成几百上千行,且每次上新服务,需要在修改路由文件代码,带来一定的风险。

2. 解决方案

  • 既然路由文件随着业务的扩展越来越庞大,那就去掉路由文件。
  • 制定对应规则,路由通过API文件名根据一定的规则对应类名,然后自动导入对应实现类,注册到Web框架中。

    2.1 制定规则

    下面这套规则只是其中一种方案,可以针对项目情况制定对应的规则,然后实现相关代码,但是整体思路基本一样。

    1. 代码目录结构,列一下简单的项目文件目录,下面以flask框架为例:

      app.py是启动文件。
      resources是API接口代码文件夹。
      services是为API接口服务的函数封装文件夹。
      如果项目还有依赖文件,也可以单独再建其他文件夹。

    2. 项目的API接口代码均放在resources文件夹下,且此文件夹只能写接口API服务代码。

    3. 接口名称命名以_连接单词,而对应文件里的类名文件名称的单词,不过换成是驼峰写法。

    4. 类的导入则通过文件名对应到类名,实现自动映射注册到web框架中。

    规则举例如下:
    如上图,resources下有一个hello_world接口,还有一个ab项目文件夹,ab下面还有一个hello_world_python接口以及子项目文件夹testab, testab下面也有一个hello_world_python.

    • 接口文件的文件名命名规范:
      文件名命名均为小写,多个单词之间使用'_'隔开,比如hello_world.py 命名正确,helloWorld.py命名错误。

    • 接口文件里的接口类Class命名是以文件名字转为驼峰格式,且首字母大写。比如hello_world.py 对应的接口类是 HelloWorld
      举例: hello_world.py

      hello_world_python.py
    1. 路由入口文件会自动映射,映射规则为:
      前缀 / 项目文件夹[...] / 文件名

      其中 前缀为整个项目的路由前缀,可以定义,也可以不定义,比如api-ab项目,可以定义整个项目的路由前缀为 ab/
      resource下面项目文件夹如果有,则会自动拼接,如果没有,则不会读取。
      举例:
      前缀为空,上图resources中的三个接口对应的路由为:

      hello_world.py ==>  /hello_worldab/hello_world_python.py ==> /ab/hello_world_pythonab/testab/hello_world_python.py ==> /ab/testab/hello _world_python

      前缀为ab/,上图resources中的三个接口对应的路由为:

      hello_world.py ==> ab/hello_worldab/hello_world_python.py ==> ab/ab/hello_world_pythonab/testab/hello_world_python.py ==> ab/ab/testab/hello_world_python
    2. 关于resources里目录结构,代码里是可以允许N层,但建议不要超过3层, 不易管理。

2.2 代码实现

python很多框架的启动和路由管理都很类似,所以这套规则适合很多框架,测试过程中有包括flask, tornado, sanic, japronto。 以前年代久远的web.py也是支持的。

完整代码地址:
https://github.com/CrystalSkyZ/PyAutoApiRoute

  1. 实现下划线命名 转 驼峰命名 函数,代码演示:

    def underline_to_hump(underline_str):'''下划线形式字符串转成驼峰形式,首字母大写'''sub = re.sub(r'(_\w)', lambda x: x.group(1)[1].upper(), underline_str)if len(sub) > 1:    return sub[0].upper() + sub[1:]return sub
  2. 实现根据字符串导入模块函数, 代码演示:

    • 通过python内置函数__import__函数实现加载类

          def import_object(name):    """Imports an object by name.    import_object('x') is equivalent to 'import x'.    import_object('x.y.z') is equivalent to 'from x.y import z'.    """    if not isinstance(name, str):            name = name.encode('utf-8')    if name.count('.') == 0:            return __import__(name, None, None)    parts = name.split('.')    obj = __import__('.'.join(parts[:-1]), None, None, [parts[-1]], 0)    try:            return getattr(obj, parts[-1])    except AttributeError:            raise ImportError("No module named %s" % parts[-1])
    • 通过importlib模块实现
      importlib.import_module(name)

    上面2种方法都可以,github上代码里2种方法都有测试。

  3. 检索resources文件夹,生成路由映射,并导入对应实现类, 代码演示如下:

    def route(route_file_path,      resources_name="resources",      route_prefix="",      existing_route=None):route_list = []    def get_route_tuple(file_name, route_pre, resource_module_name):        """        :param file_name: API file name        :param route_pre: route prefix        :param resource_module_name: resource module        """        nonlocal route_list        nonlocal existing_route        route_endpoint = file_name.split(".py")[0]        #module = importlib.import_module('{}.{}'.format(        #    resource_module_name, route_endpoint))        module = import_object('{}.{}'.format(            resource_module_name, route_endpoint))        route_class = underline_to_hump(route_endpoint)        real_route_endpoint = r'/{}{}'.format(route_pre, route_endpoint)        if existing_route and isinstance(existing_route, dict):            if real_route_endpoint in existing_route:                real_route_endpoint = existing_route[real_route_endpoint]        route_list.append((real_route_endpoint, getattr(module, route_class)))    def check_file_right(file_name):        if file_name.startswith("_"):            return False        if not file_name.endswith(".py"):            return False        if file_name.startswith("."):            return False        return True    def recursive_find_route(route_path, sub_resource, route_pre=""):        nonlocal route_prefix        nonlocal resources_name        file_list = os.listdir(route_path)        if config.DEBUG:            print("FileList:", file_list)        for file_item in file_list:            if file_item.startswith("_"):                continue            if file_item.startswith("."):                continue            if os.path.isdir(route_path + "/{}".format(file_item)):                recursive_find_route(route_path + "/{}".format(file_item), sub_resource + ".{}".format(file_item), "{}{}/".format(route_pre, file_item))                continue            if not check_file_right(file_item):                continue            get_route_tuple(file_item, route_prefix + route_pre, sub_resource)recursive_find_route(route_file_path, resources_name)if config.DEBUG:    print("RouteList:", route_list)return route_list
    • get_route_tuple函数作用是通过字符串导入类,并将路由和类以元组的方式添加到数组中。
    • check_file_right函数作用是过滤文件夹中不合法的文件。
    • recursive_find_route函数采用递归查找resources中的文件。
    • existing_route参数是将已经线上存在的路由替换新规则生成的路由,这样旧项目也是可以优化使用这套规则。

3. 应用到项目中

以flask框架为例,其余框架请看github中的代码演示。
app.py 中代码

   app = Flask(__name__)   api = Api(app)   # APi route and processing functions   exist_route = {"/flask/hello_world": "/hello_world"}   route_path = "./resources"   route_list = route(       route_path,       resources_name="resources",       route_prefix="flask/",       existing_route=exist_route)   for item in route_list:       api.add_resource(item[1], item[0])   if __name__ == "__main__":       app.run(host="0.0.0.0", port=int(parse_args.port), debug=config.DEBUG)

运行app.py之后,路由打印如下:

   RouteList: [  ('/hello_world', ),  ('/flask/ab/testab/hello_world_python_test', \            ),   ('/flask/ab/hello_world_python', )  ]

元组第一个元素则是路由,第二个元素是对应的实现类。


总结:
至此,通过制定一定规则,解放路由管理文件方案完成。 欢迎各位一起讨论其余比较好的方案,更多方案讨论可以关注微信公众号: 天澄的技术笔记 。

文件 路由 接口 代码 项目 文件夹 规则 函数 框架 前缀 文件名 方案 管理 驼峰 演示 上图 单词 字符 字符串 目录 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 什么是科技互联网 百单网互联网科技有限公司怎么样 华服互联网科技靠谱吗 互联网科技公司简介 重生之互联网科技帝国 高科技与互联网 礼当家互联网科技 顺玮阁互联网科技 掌上梦互联网科技 互联网汽车科技小镇 深圳前海聚择互联网科技有限公司 福州新华互联网科技学校 知乎 全球顶尖互联网科技公司 厦门千工互联网科技有限公司 小米互联网科技园入驻 萌小萌互联网科技河南有限公司 广州智享互联网科技 杭州科技互联网公司有哪些 瑞安市蟠桃会互联网科技有限公司 山东亿川互联网科技有限责任公司 互联网下的科技发展 关于新基建和互联网科技 有木互联网科技 科技伦理 互联网公司 广西拼得多互联网科技有限公司 小米互联网科技园设置 互联网大会黑科技排名 互联网5g黑科技有哪些 恒生互联网科技业指数调整周期 好易买互联网科技
0