ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Eve REST API 自定义 ID 字段实战:为资源接入 UUID 唯一标识

Eve REST API 自定义 ID 字段实战:为资源接入 UUID 唯一标识 后端Web框架【免费下载链接】eveREST API framework designed for human beings项目地址https://gitcode.com/gh_mirrors/ev/eve点击查看免费下载Eve 默认以 MongoDB 的ObjectId作为文档唯一标识但当业务集合使用 UUID 等自定义主键时默认的序列化、验证与 URL 解析机制将无法正常工作。本篇教程以官方文档 docs/tutorials/custom_idfields.rst 为核心骨架完整演示如何通过自定义 JSONEncoder、扩展 Validator 与配置item_url三步为 Eve 资源接入 UUID 类型的_id字段。读完本文你将能够为任意资源启用自定义 ID 类型并理解其背后的源码实现原理。背景Eve 的默认 ID 机制在 Eve 中当你配置了一个资源端点例如/invoices框架会自动为它生成对应的单文档端点/invoices/ObjectId客户端可以据此查询、编辑或删除单个文档。这一切在ID_FIELD为ObjectId类型时开箱即用默认的ID_FIELD为_id见 eve/default_settings.py默认的ITEM_LOOKUP_FIELD直接引用ID_FIELD而ITEM_URL默认值为regex([a-f0-9]{24})即匹配 24 位十六进制字符的标准 MongoDB ObjectId 字符串见 eve/default_settings.py。也就是说Eve 在构建 URL 映射时会使用item_url中定义的正则表达式来匹配单文档端点 URL 中的 ID 段并将其作为查询条件传给数据层。然而如果某个集合的唯一标识符不是ObjectId例如业务上常见的 UUID、订单号或自然键你仍然希望单文档端点正常工作就需要做一点定制工作。好消息是它完全可行而且只需要三个步骤。三步为资源接入 UUID 主键本文以invoices集合为例希望 API 暴露形如下列形式的单文档端点/invoices/48c00ee9-4dbe-413f-9fc3-d5f12a91de1c需要完成的三件事是编写一个能够把 UUID 序列化为字符串的自定义 JSONEncoder并传给 Eve 应用为数据验证层新增uuid数据类型以便校验客户端提交的 UUID 值配置invoices端点的item_url让 Eve 能够正确解析 UUID 形式的 URL。下面逐一展开。第一步自定义 JSONEncoder 序列化 UUIDEve 的默认 JSON 序列化器可以出色地处理常见数据类型datetime会被序列化为 RFC1123 字符串形如Sat, 23 Feb 1985 12:00:00 GMTObjectId也会被序列化为字符串。这些能力来自BaseJSONEncoder——Eve 内置的 JSONEncoder 子类位于 eve/io/base.py它在default()方法中处理了datetime转为 RFC1123、date/time转为 ISO 格式以及set转为 list等特殊类型其余则委托给标准库json.JSONEncoder.default()。由于 UUID 是 Eve 未知的数据类型我们需要告知实例如何序列化它。最稳妥的做法是继承 Eve 自带的BaseJSONEncoder而非直接继承标准库的JSONEncoder这样既能保留 Eve 的全部序列化能力又只需新增 UUID 的处理分支from eve.io.base import BaseJSONEncoder from uuid import UUID class UUIDEncoder(BaseJSONEncoder): JSONEconder subclass used by the json render function. This is different from BaseJSONEoncoder since it also addresses encoding of UUID def default(self, obj): if isinstance(obj, UUID): return str(obj) else: # delegate rendering to base class method (the base class # will properly render ObjectIds, datetimes, etc.) return super(UUIDEncoder, self).default(obj)从源码层面看这个编码器会在响应渲染阶段被实际调用JSONRenderer.render()在序列化响应数据时使用的是app.data.json_encoder_class见 eve/render.py而该属性在应用实例化时会被我们传入的自定义编码器覆盖见后文第四步。第二步扩展 Validator新增uuid数据类型Eve 默认会在每次插入新文档时自动生成ObjectId类型的唯一标识。这在本场景中并非我们想要的这里希望由客户端自行提供UUID 标识并且服务端要校验其确实是合法的 UUID。为此需要扩展 Eve 的验证层。Eve 的验证器基于 Cerberus其数据层实现是eve.io.mongo.Validator见 eve/io/mongo/validation.py。从源码可以看到Eve 内置了诸如_validate_type_objectid、_validate_type_decimal、_validate_type_media以及一系列 GeoJSON 类型验证方法——这正是 Cerberus 的约定类型验证方法命名为_validate_type_type_name。因此要新增uuid类型只需实现同名方法from eve.io.mongo import Validator from uuid import UUID class UUIDValidator(Validator): Extends the base mongo validator adding support for the uuid>invoices { # this resource item endpoint (/invoices/id) will match a UUID regex. item_url: regex([a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}), schema: { # set our _id field of our custom uuid type. _id: {type: uuid}, }, } DOMAIN { invoices: invoices }两点关键说明item_url使用regex()转换器Eve 在 eve/flaskapp.py 中定义了RegexConverter继承自 Werkzeug 的BaseConverter并在应用初始化时将其注册到 URL 映射的regex转换器名下见 eve/flaskapp.py。因此item_url中可以放心使用regex(...)语法。上述正则匹配的是标准 UUID含可选的连字符变体且第 3 段以4开头、第 4 段首字符属于[89ab]即 RFC 4122 的 v4 格式。schema 中声明_id的类型为uuid这告诉验证层该字段必须通过_validate_type_uuid的校验。全局配置技巧如果 API 的所有资源都支持 UUID 作为唯一文档标识那么不必为每个资源单独设置item_url直接修改全局的ITEM_URL为上述 UUID 正则即可见 eve/default_settings.py 中默认ITEM_URL的用法。从源码看eve/flaskapp.py 中每个资源在注册时会settings.setdefault(item_url, self.config[ITEM_URL])即资源级item_url缺省时回落到全局ITEM_URL。第四步把定制组件注入 Eve 应用所有拼图就绪后最后一步是在实例化应用时把自定义类传给 Eve。Eve 需要知道新的数据类型以构建 URL 映射因此必须在应用创建之初就传入app Eve(json_encoderUUIDEncoder, validatorUUIDValidator)从 eve/flaskapp.py 的Eve.__init__签名可以看到Eve()支持validator、data、auth、redis、url_converters、json_encoder、media等注入点。在初始化流程中若传入json_encoder则self.data.json_encoder_class会被覆盖为自定义编码器见 eve/flaskapp.py此后所有 JSON 响应都会经由UUIDEncoder序列化对应 eve/render.py 中的clsapp.data.json_encoder_class而validator则会被用于后续所有文档的 POST/PATCH 校验。客户端如何提交 UUID牢记一点如果使用了自定义ID_FIELD值就不应依赖 MongoDB以及 Eve自动生成ID_FIELD。客户端必须在请求体中显式携带_id值例如POST {name:bill, _id:48c00ee9-4dbe-413f-9fc3-d5f12a91de1c}随后即可通过/invoices/48c00ee9-4dbe-413f-9fc3-d5f12a91de1c访问该文档进行 GET、PATCH、PUT、DELETE 等单文档操作。关于 UUID 存储表示的注意事项默认情况下Eve 会将 PyMongo 的UuidRepresentation设置为standard。这一点在 eve/default_settings.py 中可以看到默认值MONGO_OPTIONS {connect: True, tz_aware: True, uuidRepresentation: standard}standard表示允许无缝处理现代 Python 生成的 UUID 值即按 RFC 4122 标准二进制格式存储。如果需要更改默认表示方式可以通过修改MONGO_OPTIONS中的uuidRepresentation值来实现例如设置为pythonLegacy、javaLegacy或unspecified以兼容来自其他语言/旧版本驱动的存量数据。相关配置项同样位于 eve/default_settings.py可根据实际数据源需求调整。扩展思路自定义类型不止 UUID本教程以 UUID 为例但整套模式完全适用于其他自定义主键类型核心规律是序列化继承eve.io.base.BaseJSONEncoder在default()中处理目标类型并委托给父类验证继承eve.io.mongo.Validator实现_validate_type_类型名方法路由为资源配置匹配该类型字符串形态的item_url借助内置regex()转换器或通过Eve(url_converters...)注入自定义 Werkzeug URL 转换器注入在Eve(json_encoder..., validator...)时一并传入。小结通过自定义 JSONEncoder、扩展 Validator 以及配置item_url三个步骤即可让 Eve 的单个文档端点支持 UUID或其他自定义类型作为唯一标识序列化层负责把 UUID 渲染为字符串eve/io/base.py验证层负责校验客户端提交值的合法性eve/io/mongo/validation.py路由层负责解析 URL 中的 UUID 段eve/flaskapp.py而应用实例化参数负责把三者组装起来。配合MONGO_OPTIONS中uuidRepresentation的设置即可在生产环境中安全地以 UUID 作为文档主键同时保持客户端自行提交_id的完整控制权。赞分享后端Web框架【免费下载链接】eveREST API framework designed for human beings项目地址https://gitcode.com/gh_mirrors/ev/eve点击查看免费下载相关推荐PowerToys 文件锁匠指南快速找到文件占用进程并结束它PowerToys 文件锁匠指南快速找到文件占用进程并结束它 删除文件时弹出文件正在 Microsoft Word 中打开无法执行操作重启系统往往不是后端Web框架AI-Render突破3D创作瓶颈的革命性Blender插件深度解析AI Render突破3D创作瓶颈的革命性Blender插件深度解析 在当今数字创作领域3D艺术家们面临着创意实现与技术门槛的双重挑战。传统渲染流程需要耗费人工智能AI 应用媒体生成NocoBase UUID 字段详解唯一标识自动生成机制与跨系统同步配置实战NocoBase UUID 字段详解唯一标识自动生成机制与跨系统同步配置实战 在 NocoBase 中UUID 字段用于为记录生成通用唯一标识是外部系统同低代码后端前端人工智能AI 应用工作流自动化上一篇OpCore-Simplify15分钟快速构建完美黑苹果EFI的终极指南下一篇终极黑苹果配置神器OpCore-Simplify如何让你15分钟搞定OpenCore EFI创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表