Spyne结合DispatcherMiddleware时,如何传递ctx.method_request_string至中间件?
解决方案
方法1:修改WSGI环境变量(最直接方案)
DispatcherMiddleware基于WSGI规范工作,所有请求上下文都存储在environ字典中。你可以在Spyne处理流程的早期,将ctx.method_request_string写入environ的自定义字段,甚至直接覆盖标准的REQUEST_METHOD(如果确定该值是传给后端的准确方法),让DispatcherMiddleware读取这个值来做路由判断。
示例代码:
from spyne import Application, rpc, ServiceBase, Unicode from spyne.protocol.soap import Soap11 from spyne.server.wsgi import WsgiApplication from flask import Flask from werkzeug.middleware.dispatcher import DispatcherMiddleware # 自定义WSGI中间件,负责传递Spyne ctx中的方法信息 class SpyneMethodMiddleware: def __init__(self, app): self.app = app def __call__(self, environ, start_response): # 从environ中获取Spyne上下文(后续通过钩子自动注入) ctx = environ.get('spyne_ctx') if ctx: # 写入自定义字段供DispatcherMiddleware读取 environ['CUSTOM_REQUEST_METHOD'] = ctx.method_request_string # 若要直接修改传给后端的请求方法,可覆盖标准字段 # environ['REQUEST_METHOD'] = ctx.method_request_string return self.app(environ, start_response) # 定义Spyne服务 class HelloService(ServiceBase): @rpc(Unicode, _returns=Unicode) def say_hello(self, ctx, name): return f"Hello, {name}!" # 创建Spyne应用并注册事件钩子 spyne_app = Application( [HelloService], 'spyne.demo', in_protocol=Soap11(validator='lxml'), out_protocol=Soap11() ) # 注册Spyne事件钩子,自动将ctx注入WSGI环境 def inject_ctx_to_environ(ctx): ctx.transport.wsgi_env['spyne_ctx'] = ctx spyne_app.event_manager.add_listener('method_call', inject_ctx_to_environ) # 包装Spyne应用 wrapped_spyne_app = SpyneMethodMiddleware(WsgiApplication(spyne_app)) # Flask应用示例 flask_app = Flask(__name__) @flask_app.route('/') def index(): return "Flask Service" # 自定义DispatcherMiddleware,根据自定义字段路由 class CustomDispatcher(DispatcherMiddleware): def __call__(self, environ, start_response): custom_method = environ.get('CUSTOM_REQUEST_METHOD') # 根据准确的方法值路由到对应服务 if custom_method == 'SAY_HELLO': return self.apps['/soap'](environ, start_response) elif custom_method == 'GET_INDEX': return self.apps['/'](environ, start_response) # 兜底用默认路由逻辑 return super().__call__(environ, start_response) # 组合最终应用 application = CustomDispatcher(flask_app, { '/soap': wrapped_spyne_app })
方法2:通过Spyne事件钩子传递信息
Spyne内置了多种事件钩子,可在请求处理的关键阶段触发自定义逻辑。你可以利用method_call钩子,自动将ctx.method_request_string写入WSGI环境,无需在每个服务方法中手动处理。
核心代码片段:
from spyne import EventManager def pass_method_to_environ(ctx): # 将准确的方法名写入WSGI环境 ctx.transport.wsgi_env['CUSTOM_REQUEST_METHOD'] = ctx.method_request_string # 给Spyne应用注册钩子 spyne_app.event_manager.add_listener('method_call', pass_method_to_environ)
方法3:更新请求头(针对依赖头信息的场景)
如果后端服务依赖自定义请求头传递方法信息,你可以在WSGI环境中修改对应的HTTP_*前缀字段,比如设置X-Accurate-Method头:
environ['HTTP_X_ACCURATE_METHOD'] = ctx.method_request_string
后端服务就能通过请求头获取到这个准确的方法值。
内容的提问来源于stack exchange,提问作者John Gedik
相关产品推荐
相关产品推荐

