尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Tyk Coprocess 插件框架实战:使用 Python、Lua 与 gRPC 编写自定义 API 中间件

发布时间:2026/9/23 21:56:52

资讯中心
01
ARTICLE

Tyk Coprocess 插件框架实战:使用 Python、Lua 与 gRPC 编写自定义 API 中间件

Tyk Coprocess 插件框架实战:使用 Python、Lua 与 gRPC 编写自定义 API 中间件
Tyk Coprocess 插件框架实战使用 Python、Lua 与 gRPC 编写自定义 API 中间件【免费下载链接】tykOpen Source API and AI Gateway supporting REST, GraphQL, TCP, gRPC and MCP (Model Context Protocol)项目地址: https://gitcode.com/gh_mirrors/ty/tykCoprocessCo-Process是 Tyk API 网关提供的富插件rich plugin机制它允许开发者使用自己熟悉的语言编写中间件挂载到 Tyk 的标准请求处理链路上。本文基于 coprocess/README.md 及仓库源码系统讲解 Coprocess 的进程内消息传递架构、Dispatcher 接口、五类 Hook 的语义、Python/Lua/gRPC 三种驱动的接入方式、ID Extractor 认证缓存、Coprocess Gateway API 以及构建与测试方法读完即可在自有 API 定义中配置并调试自定义中间件。Coprocess 是什么为什么需要它Tyk 网关本身以 Go 编写原生支持 JavaScript 插件goja/otto等脚本化中间件。但很多团队更希望在 Python、Lua、Ruby、Java 等语言中复用已有的认证、限流、转换逻辑。Coprocess 正是为此设计它通过进程内消息传递把 Tyk 的请求对象、会话对象和 API 定义翻译成目标语言可处理的数据结构让任意语言都能以 Hook 的形式参与 Tyk 的中间件链路。从源码结构看整个特性被组织在 coprocess/ 目录下包含proto/定义消息格式的 Protocol Buffers 文件及其生成脚本bindings/预生成的多语言绑定Python、Ruby、Java、Cpython/、lua/、grpc/三种驱动的实现与文档dispatcher.goDispatcher 接口定义api.hC 语言桥接头文件。核心架构基于 Protocol Buffers 的进程内消息传递Coprocess 的互操作性建立在两层消息结构之上传输层目标语言的 C 桥接函数接收/返回一个CoProcessMessage结构其中p_data指向序列化数据的指针length表示数据长度。该结构在 coprocess/api.h 中定义struct CoProcessMessage { void* p_data; int length; };业务层p_data解包后是完整的CoProcessObject数据它携带 Hook 类型、HTTP 请求、Tyk 会话和 API 定义等信息。原文档以 Go 结构描述其形态对应 Protobuf 消息coprocess.Object见 coprocess/proto/coprocess_object.prototype CoProcessObject struct { HookType string Request CoProcessMiniRequestObject Session SessionState Metadata map[string]string Spec map[string]string }其中HookType本次调用触发的 Hook 类型见下文 Hook 语义RequestMiniRequestObject包含 headers、params、body、url、method 等请求字段Session当前 key/用户对应的 Tyk 会话状态Metadata动态元数据SpecAPI 定义信息如 APIID、OrgID 等是插件识别属于哪个 API的关键依据。Go 侧与目标语言之间的桥接通过 cgo。这也解释了为什么 Coprocess 被称为进程内插件插件代码运行在 Tyk 进程内部通过 C 层直接交换内存数据不引入额外的网络往返gRPC 驱动除外。Protobuf 消息的字段细节从 coprocess/proto/coprocess_mini_request_object.proto 可以看到MiniRequestObject的完整字段这对编写中间件至关重要headers只读此前中间件注入的请求头set_headers/delete_headers要追加/删除的请求头body/raw_body请求体字符串与原始字节两种形式url/request_uri/scheme/method请求的 URL、原始 URI含查询串、协议与 HTTP 方法params只读、add_params、delete_params查询参数的读取与修改return_overrides直接覆盖 Tyk 对当前请求的响应状态码、响应体、响应头常用于在中间件内直接终止请求并返回自定义错误。Proto 文件与绑定生成Coprocess 的所有消息格式由 coprocess/proto/ 下的.proto文件定义包括coprocess_common.protoHookType枚举与StringSlicecoprocess_object.protoObject、Event、EventReply与DispatchergRPC 服务coprocess_mini_request_object.proto请求对象coprocess_response_object.proto响应对象用于 Response Hookcoprocess_return_overrides.proto响应覆盖结构coprocess_session_state.proto会话状态。原文档提示如需修改 proto 并更新绑定参考proto/目录下的生成脚本。当前仓库中该目录包含 codegen.py 与 Taskfile.yml负责为各语言重新生成绑定代码。仓库内 coprocess/bindings/ 已预置生成结果Python*_pb2.py、Ruby*_pb.rb、Java*.java、C*.pb.cc/.pb.hgRPC 驱动可直接复用这些文件。HookType 枚举五种 Hook 的完整语义coprocess/proto/coprocess_common.proto 中定义了HookType枚举原文档描述了其中四类源码则给出了完整集合与精确语义枚举值名称执行时机1Pre在从请求头/参数中提取任何认证信息之前执行同时适用于 keyless 与受保护 API2Post在认证、校验、限流、配额等中间件执行完毕后、请求被代理到上游之前执行3PostKeyAuth紧随认证流程之后执行4CustomKeyCheck作为自定义认证中间件整体替代 Tyk 内置认证5Response上游 API 响应后执行可修改返回给客户端的 HTTP 响应Coprocess Dispatcher 接口coprocess/dispatcher.go 定义了coprocess.Dispatcher接口它是所有驱动PythonDispatcher、gRPC 等必须实现的门面type Dispatcher interface { Dispatch(*Object) (*Object, error) DispatchWithContext(context.Context, *Object) (*Object, error) DispatchEvent([]byte) DispatchObject(*Object) (*Object, error) LoadModules() HandleMiddlewareCache(*apidef.BundleManifest, string) Reload() }各方法职责如下Dispatch核心分发入口。接收指向CoProcessObject的指针并返回同类型对象。它会在每个已配置的 Hook、每次请求时被调用。传统上该方法在目标语言侧只做一次函数调用如 Python 驱动的dispatch_hook真正的中间件查找与执行逻辑放在语言内部处理——因为不同语言加载、引用和调用中间件的方式差异很大。DispatchWithContext携带context.Context的分发入口用于链路追踪trace propagation。DispatchEvent把 Tyk 事件分发给目标语言。注意它不使用 Protocol Buffers入参是 JSON 编码的[]byte目标语言侧按char*接收后自行做 JSON 解码这样做是为了保持扩展性。DispatchObjectgRPC 驱动使用的分发入口直接传递反序列化后的coprocess.Object。LoadModulesCP 绑定首次启动时调用Lua 驱动使用。HandleMiddlewareCachebundle 加载后用于缓存中间件清单Lua 驱动使用。Reload触发热重载时调用典型用途是重载目标语言中的脚本或模块。以 Python 为例gateway/coprocess_python.go 中的PythonDispatcher.DispatchWithContext展示了完整调用链将coprocess.Object用proto.Marshal序列化 → 通过 CPython C API 获取dispatcherInstance.dispatch_hook属性 → 传入字节串并调用 → 从返回值中取回新对象字节 →proto.Unmarshal回 Go 结构。整个调用被pythonLock互斥锁保护避免多 goroutine 并发操作 Python 解释器。Python 侧的TykDispatcher见 coprocess/python/dispatcher.py则负责按 bundle 维护 hook 表load_bundle把中间件打包进hook_tabledispatch_hook依据object.spec[bundle_hash]与object.hook_name找到对应的 Python 函数执行dispatch_event依据事件的 APIID 与 handler 名称分发事件reload留作重载钩子。Hook 语义详解中间件在请求链中的位置原文档明确指出 Dispatcher 遵循标准中间件链逻辑为自定义中间件行为提供简单的挂载机制。以 Python 装饰器为例coprocess/python/tyk/decorators.pyPre/Post/PostKeyAuth/CustomKeyCheck/Event五个装饰器分别对应相应 Hook装饰器内部按函数参数个数3 或 4 个自动适配调用签名Pre在认证之前运行可对请求做任意预处理如注入请求头、改写请求体Post在认证、校验、限流、配额之后、代理到上游之前运行用于把请求后处理后再发给上游 APIPostKeyAuth认证流程刚结束即运行适合做基于认证结果的附加检查CustomAuthCheck即枚举中的CustomKeyCheck完全取代 Tyk 内置认证实现自有认证机制调用签名为(request, session, metadata, spec)Response上游响应返回后运行可改写响应。需要特别强调的是所有 Hook 类型都支持链式挂载chaining唯独自定义认证auth_check例外——每个 API 只能配置一个CustomAuthCheck。三种驱动Python、Lua 与 gRPCPython 驱动Python 是文档中描述最详细的驱动支持 Python 3.x。Tyk 会加载middleware/python目录下的全部模块custom_middleware中的name字段即 Python 函数名。一个完整的 Python 中间件参考 middleware/python 目录与 coprocess/python/README.mdfrom tyk.decorators import * Pre def MyPreMiddleware(request, session, spec): print(my_middleware: MyPreMiddleware) return request, session Post def MyPostMiddleware(request, session, spec): print(my_middleware: MyPostMiddleware) return request, sessionPython 驱动的构建依赖详见 coprocess/python/README.mdPython 3.xGo 工具链Cython如需修改并重编译 Gateway API 绑定protobuf Python 模块pip3 install protobuf3.20.2gRPC 模块pip3 install grpcio。Cython 的引入原因值得说明原文档指出Cython 将.pyx文件编译为 C 源文件.c/.h后直接参与 cgo 构建作为cffi的替代方案——cffi需要用户先安装模块增加了部署步骤而 Cython 方案在构建结束后绑定已成为 Tyk 二进制的一部分运行时无需.pyx文件。cythonize脚本会给生成的 C 文件打上// build coprocess与// build python标签确保普通构建时 Go 编译器忽略这些 C 绑定文件。Lua 驱动Lua 支持见 coprocess/lua/README.md唯一的硬性依赖是lua-cjson用于 JSON 编解码推荐通过 luarocks 安装% luarocks install lua-cjsonLua 驱动的核心代码位于 coprocess/lua/包括绑定头文件 binding.h、Bundle 加载器 bundle.lua 以及tyk/core.lua、tyk/request.lua等运行时库。gRPC 驱动gRPC 驱动允许把中间件逻辑放到任意 gRPC 后端进程中官方支持的语言非常广泛C、Java、Python、Go、Ruby、C#、Node.js、Objective-C、PHP 等。由于 gRPC 本身基于 Protocol BuffersTyk 的 coprocess/proto/coprocess_object.proto 直接定义了 Dispatcher 服务契约service Dispatcher { rpc Dispatch (Object) returns (Object) {} rpc DispatchEvent (Event) returns (EventReply) {} }工作流程为Tyk 启动时按tyk.conf全局配置连接你的 gRPC 服务器支持本地 UNIX socket 或网络 TCPTyk 收到请求后调用 gRPC 服务器由后者执行实际的中间件任务转换、认证等。仓库提供了 Ruby 示例 coprocess/grpc/ruby/sample_server.rb 与 Python 示例 coprocess/bindings/python/sample_server.py。gRPC 全局配置tyk.confcoprocess_options: { enable_coprocess: true, coprocess_grpc_server: tcp://127.0.0.1:5555 }, enable_bundle_downloader: true, bundle_base_url: http://my-bundle-server.com/bundles/, public_key_path: /path/to/my/pubkey,enable_coprocess开启富插件特性coprocess_grpc_servergRPC 服务器地址仅 gRPC 插件需要enable_bundle_downloader开启 bundle 下载器bundle_base_urlbundle 基础 URL。若 API 设置中指定了test-bundleTyk 会拉取http://my-bundle-server.com/bundles/test-bundlepublic_key_path用于校验已签名 bundle 的公钥使用未签名 bundle 时可省略。gRPC API 配置enable_coprocess_auth: true, custom_middleware: { pre: [ { name: MyPreMiddleware, require_session: false } ], auth_check: { name: MyAuthCheck }, driver: grpc },enable_coprocess_auth开启 Coprocess 认证custom_middleware中driver: grpc指定驱动auth_check配置自定义认证处理器。ID Extractor 与认证缓存ID Extractor 是一个非常有用的机制它允许 Tyk 缓存认证 ID从而让部分请求不必触达 Coprocess 后端即可完成认证显著降低插件调用开销。提取规则在 API 定义的custom_middleware中按 API 配置custom_middleware: { pre: [ { name: MyPreMiddleware, require_session: false } ], id_extractor: { extract_from: header, extract_with: value, extractor_config: { header_name: Authorization } }, driver: grpc },配置项说明extract_from从请求的哪个位置提取认证 ID如header、url等extract_with采用哪种提取策略最简单的是value直接取整个值作为 IDextractor_config提取策略的附加参数如上例的header_name: Authorization指明从哪个请求头取值。Tyk 提供了一组 ID Extractor 以覆盖最常见的用例value extractor是最简单的一种Python 驱动的对应测试见 coprocess/python/coprocess_id_extractor_python_test.go。Coprocess Gateway API从插件回调 Go 能力gateway/coprocess_api.go 提供了网关 API 与 C 语言之间的桥接。任何需要导出的函数必须带//export注释例如触发 Tyk 系统事件//export TykTriggerEvent func TykTriggerEvent( CEventName *C.char, CPayload *C.char ) { eventName : C.GoString(CEventName) payload : C.GoString(CPayload) FireSystemEvent(tykcommon.TykEvent(eventName), EventMetaDefault{ Message: payload, }) }对应的 C 头文件声明位于 coprocess/api.h#ifndef TYK_COPROCESS_API #define TYK_COPROCESS_API extern void TykTriggerEvent(char* event_name, char* payload); #endif各语言绑定通过包含该头文件或内联声明并借助类似ffi的机制以适当参数调用它。仓库中实际导出的完整 API 集合包括四个函数见 coprocess/api.h 与 gateway/coprocess_api.go函数用途实现要点TykStoreData(key, value, ttl)向 Redis 写入键值带过期时间键前缀为coprocess-data:使用带 1 秒超时的 context 写存储TykGetData(key)从 Redis 读取键值读取失败时返回空串TykTriggerEvent(event_name, payload)触发 Tyk 系统事件封装为EventMetaDefault{Message: payload}CoProcessLog(msg, level)以指定级别debug/error/warning/info写入 Tyk 日志日志带python前缀字段如果正在构建 Cython 模块参考调用方式如下cdef extern: void TykTriggerEvent(char* event_name, char* payload); def call(): event_name my event.encode(utf-8) payload my payload.encode(utf-8) TykTriggerEvent( event_name, payload )Python 侧对 Gateway API 的封装是 coprocess/python/tyk/gateway.pyxCython 源码它暴露了TykGateway模块。示例用法从 Python 中间件中读写 Redis 键from tyk.decorators import * from gateway import TykGateway as tyk Pre def SetKeyOnRequest(request, session, spec): tyk.store_data( my_key, expiring_soon, 15 ) val tyk.get_data(cool_key) return request, session这些函数的端到端行为由 coprocess/coprocess_test.go 中的TestCoProcessGetSetData、TestCoProcessTykTriggerEvent等测试用例验证。基本用法在 API 定义中挂载 Coprocess 中间件使用 Coprocess 中间件的标准方式是在 API 定义中声明custom_middleware字段。原文档给出的完整示例涵盖全部 Hook 类型custom_middleware: { pre: [ { name: MyPreMiddleware, require_session: false }, { name: AnotherPreMiddleware, require_session: false } ], post: [ { name: MyPostMiddleware, require_session: false } ], post_key_auth: [ { name: MyPostKeyAuthMiddleware, require_session: true } ], auth_check: { name: MyAuthCheck }, driver: python }要点归纳pre、post、post_key_auth均为数组支持链式挂载多个中间件Tyk 按数组顺序执行auth_check为对象非数组只能配置一个自定义认证处理器require_session该 Hook 是否要求请求已认证即能否访问session对象。post_key_auth中的中间件通常设为truedriver指定驱动类型取值为python、lua或grpc。仓库中的完整可运行示例见 apps/coprocess_app_sample.json含pre/post中间件的 Python 示例 API与 apps/coprocess_app_sample_protected.json受保护 API 示例。用 Python 编写事件处理器除了请求中间件还可以用 Python 编写 Tyk 事件监听器。第一步是在 API 定义中配置自定义事件处理器handler_name固定为cp_dynamic_handlerhandler_meta.name指向 Python 函数名... event_handlers: { events: { AuthFailure: [ { handler_name: cp_dynamic_handler, handler_meta: { name: my_handler } } ] } }, ...第二步在event_handlers目录中编写对应函数参考 event_handlers/my_handler.pyfrom tyk.decorators import Event Event def my_handler(event, spec): print(-- my_handler:) print( Event:, event) print( Spec:, spec)上例监听AuthFailure事件每次认证失败都会触发。事件触发时Tyk 会把形如下面的 Python 对象传给处理器{ TimeStamp: 2016-08-19 11:13:31.537047694 -0400 PYT, Meta:{ Path:/coprocess-auth-tyk-api-test/, Origin:127.0.0.1, Message:Auth Failure, OriginatingRequest:R0VUIC9jb3Byb2Nlc3MtYXV0aC10eWstYXBpLXRlc3QvIEhUVFAvMS4xDQpIb3N0OiAxMjcuMC4wLjE6ODA4MA0KVXNlci1BZ2VudDogY3VybC83LjQzLjANCkFjY2VwdDogKi8qDQpBdXRob3JpemF0aW9uOiAxDQoNCg, Key: }, Type: AuthFailure }可通过向受保护的 Coprocess API 发送非法认证头来验证curl http://127.0.0.1:8080/coprocess-auth-tyk-api-test/ -H Authorization: invalidtoken对应的事件分发链路在 coprocess/coprocess_test.go 的TestCoProcessDispatchEvent中有端到端验证测试触发EventAuthFailure后通过CoProcessDispatchEvent通道接收 JSON 包装对象并校验事件类型与 Meta 字段。构建说明Build Tags 与多语言编译Coprocess 通过 Go 的 build tag 机制按需编译避免普通构建引入 C 依赖go build -tags coprocess pythongo build -tags coprocess somelanguage规则说明每种语言必须实现一个CoProcessInit函数在使用coprocessbuild tag 时从main函数调用Python 侧对应 gateway/coprocess_python.go 的PythonInit/PythonLoadDispatcher/PythonNewDispatcher初始化流程完整封装在NewPythonDispatcher中仅使用coprocesstag 而不指定任何语言 tag 会构建失败标准构建依然可用go build。此时 coprocess/coprocess_dummy.go 提供哑CoProcessInit实现该文件在启用coprocesstag 时被忽略因为预期由具体语言实现。测试运行 Coprocess 相关测试必须带上coprocessbuild taggo test -tags coprocess go test -run CoProcess -tags coprocess测试覆盖范围见 coprocess/coprocess_test.goTestCoProcessDispatch/TestCoProcessDispatchEvent/TestCoProcessReloadDispatcher 三个核心方法TestCoProcessSerializationcoprocess.Object序列化长度校验TestCoProcessGetSetData/TestCoProcessTykTriggerEventGateway API 的存取与事件触发TestCoProcessMiddleware/TestCoProcessObjectPostProcess中间件链执行与请求头/参数的增删改TestCoProcessAuth自定义认证CustomKeyCheck的 403 拒绝路径TestCoProcessReturnOverrides通过ReturnOverrides直接覆盖响应自定义状态码、响应体与响应头。小结Coprocess 是 Tyk 将请求处理链开放给外部语言的关键机制以 Protocol Buffers 定义消息契约、以 cgo 完成进程内桥接gRPC 驱动则为进程间通信、以 Dispatcher 接口统一分发逻辑、以五类 Hook 精确定位执行时机。无论你希望用 Python 快速编写预处理中间件、用 Lua 做轻量转换还是把认证逻辑下沉到独立的 gRPC 服务coprocess/README.md 与本文梳理的源码路径dispatcher.go、api.h、coprocess_api.go、coprocess_object.proto都能帮助你快速定位实现并开始二次开发。【免费下载链接】tykOpen Source API and AI Gateway supporting REST, GraphQL, TCP, gRPC and MCP (Model Context Protocol)项目地址: https://gitcode.com/gh_mirrors/ty/tyk创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。