Python中如何处理CGI代码与业务逻辑的耦合问题?

现在业务开发(大部分用 python)中遇到一个问题,业务代码和 CGI 接口的代码是同一套代码,CGI 接口使用其中的一部分数据。这样就出现两个思路问题:

1、在编写 CGI 代码时简单的做法是直接通过路径引用业务代码编写,代码耦合过重,CGI 扩容,配置管理和灰度基本不可能;
2、在编写 CGI 代码时重新写一份逻辑,与业务代码解耦。但是会出现业务逻辑调整忘记修改 CGI 代码的情况,出现问题;

感觉两条路都有坑,严重制约业务开发进程,但是不知道哪里错了,求大佬指导~

ps:
1、业务中有页面展示的部分,CGI 不可缺少;
2、现阶段用打包走 docker 流程还在踩坑,暂时无法使用;
3、CGI 的分布式配置管理不知道该如何做;


Python中如何处理CGI代码与业务逻辑的耦合问题?

12 回复

你说的 CGI 是指 common gateway interface 吗?


在Python里处理CGI代码和业务逻辑的耦合,核心就是把处理HTTP请求的代码(CGI部分)和实际干活的代码(业务逻辑)分开。一个直接有效的办法是采用MVC(或类似)的架构模式,即使不用框架也能自己组织。

下面是一个简单的例子,展示怎么把它们拆开:

1. 业务逻辑层 (business_logic.py) 这里纯粹是业务功能,比如计算、数据处理,完全不知道CGI或HTTP。

# business_logic.py
class UserService:
    @staticmethod
    def get_user_info(user_id):
        # 模拟从数据库获取用户信息
        users = {
            1: {"name": "Alice", "email": "alice@example.com"},
            2: {"name": "Bob", "email": "bob@example.com"}
        }
        return users.get(user_id, {"error": "User not found"})

    @staticmethod
    def create_user(name, email):
        # 这里应该是创建用户的逻辑,比如保存到数据库
        # 返回创建结果
        return {"status": "success", "message": f"User {name} created", "email": email}

2. CGI处理层 (cgi_handler.py) 这一层负责解析HTTP请求、调用业务逻辑、并生成HTTP响应。它只做“胶水”工作。

# cgi_handler.py
import cgi
import json
from business_logic import UserService

def handle_request(environ, start_response):
    # 设置响应头
    headers = [('Content-type', 'application/json; charset=utf-8')]
    
    # 获取请求方法和路径
    method = environ.get('REQUEST_METHOD', 'GET')
    path = environ.get('PATH_INFO', '')
    
    response_data = {}
    status = '200 OK'
    
    # 路由:根据路径和方法调用不同的处理函数
    if path == '/user' and method == 'GET':
        # 解析查询参数
        field_storage = cgi.FieldStorage(fp=environ['wsgi.input'], environ=environ)
        user_id = field_storage.getvalue('id')
        if user_id:
            user_info = UserService.get_user_info(int(user_id))
            response_data = user_info
        else:
            status = '400 Bad Request'
            response_data = {"error": "Missing user id"}
    
    elif path == '/user' and method == 'POST':
        # 解析POST表单数据
        field_storage = cgi.FieldStorage(fp=environ['wsgi.input'], environ=environ)
        name = field_storage.getvalue('name')
        email = field_storage.getvalue('email')
        if name and email:
            result = UserService.create_user(name, email)
            response_data = result
            status = '201 Created'
        else:
            status = '400 Bad Request'
            response_data = {"error": "Missing name or email"}
    
    else:
        status = '404 Not Found'
        response_data = {"error": "Endpoint not found"}
    
    # 构建响应
    response_body = json.dumps(response_data, ensure_ascii=False).encode('utf-8')
    headers.append(('Content-Length', str(len(response_body))))
    start_response(status, headers)
    return [response_body]

# 用于CGI入口
if __name__ == '__main__':
    # 这是一个简单的WSGI兼容接口,便于在支持WSGI的服务器或cgi模式下运行
    from wsgiref.handlers import CGIHandler
    CGIHandler().run(handle_request)

3. 部署说明business_logic.pycgi_handler.py 放在你的CGI可执行目录(如Apache的 cgi-bin)。你的CGI入口文件(比如 index.cgi)可以非常精简,只需调用处理层:

#!/usr/bin/env python3
# index.cgi
import cgi_handler

if __name__ == '__main__':
    cgi_handler.handle_request()

确保CGI文件有执行权限(chmod +x index.cgi)。

总结一下:

  • 业务逻辑 单独成模块或类,只关心数据规则。
  • CGI处理层 负责HTTP的脏活:解析请求、参数、调用业务逻辑、处理异常、组装JSON/HTML响应。
  • 两者通过清晰的函数/方法接口通信,业务逻辑不依赖任何CGI环境变量或函数。

这样拆开之后,你的业务逻辑可以独立测试,甚至以后换掉CGI(比如用Flask、FastAPI)时,业务代码基本不用动。

简单建议:用分层设计把HTTP处理和核心逻辑彻底分开。

CGI 有点 old school 了

cgi ? python 难道不应该是 wsgi 吗?

,是的

,链接打不开兄弟

,用的是 flask

,flask 做的接口

《架构整洁之道》推荐序:软件开发的上古智慧

自己去搜一下吧。

,好的,感谢大佬

回到顶部