我什么时候会在 monogoengine 的内置 JSON 序列化(from_json 和 to_json)上使用像 marshmallow 这样的外部序列化器?

When would I use an external serializer like marshmallow over monogoengine's in-built JSON serialization (from_json and to_json)?

我正在使用 Flask-RESTful and their documentation says that they are planning to deprecate their object serialization (reqparse) in favor of serializers like marshmallow 在 Python 中编写一个简单的 REST API 我的 API 正在使用 Flask MongoEngine.

从 MongoDB 文档存储读取和写入

我非常感谢一个用例示例,在该示例中,我会选择使用 Marshmallow 等外部序列化程序,而不是 Document 对象上的 MongoEngine 内置序列化程序。

Mongo 使用 BSON,他们在 python.
中实现了 dedicated parser util 来自来源:

反序列化:

from bson.json_util import loads
loads('[{"foo": [1, 2]}, {"bar": {"hello": "world"}}, {"code": {"$scope": {}, "$code": "function x() { return 1; }"}}, {"bin": {"$type": "80", "$binary": "AQIDBA=="}}]')

# >>> [{u'foo': [1, 2]}, {u'bar': {u'hello': u'world'}}, {u'code': Code('function x() { return 1; }', {})}, {u'bin': Binary('...', 128)}]

序列化:

from bson import Binary, Code
from bson.json_util import dumps
dumps([{'foo': [1, 2]},
       {'bar': {'hello': 'world'}},
       {'code': Code("function x() { return 1; }", {})},
       {'bin': Binary(b"")}])

# >>> '[{"foo": [1, 2]}, {"bar": {"hello": "world"}}, {"code": {"$code": "function x() { return 1; }", "$scope": {}}}, {"bin": {"$binary": "AQIDBA==", "$type": "00"}}]'

当您尝试 serialize/deserialize 的对象是 BSON 时,您需要使用 mongo 的 dumpsloads 否则将无法正确解析。当它是常规 JSON 时,你可以使用任何你喜欢的。

本质区别在于 marshmallow 验证

您不只是从 Internet 上获取任何数据并将其填充到您的数据库中。验证可防止输入错误数据(恶意或错误)。即使数据来自受信任的用户,验证它以确保数据库完整性也是个好主意。

Marshmallow 与 flask-restplus 一样,提供验证器,不仅可以验证类型,还可以验证值(min/max 用于数字,min/max 用于字符串,min/max 用于日期等。 ,您甚至可以创建自己的验证器)。

此外,API 并不总是全部是 CRUD。 API 和 DB 之间可能有一些业务代码,有 Python 个对象是很好的。 Mongo 的 BSON 解析器不会那样做。

Mongo引擎提供验证,但它是在DB之前,而验证应该在进入API时进行。


顺便说一句,flask-restful 中的内部 [de|] 序列化已计划弃用一段时间,而且事情似乎停滞不前 (GH issue #9)。我认为有人在使用 flask-restplus + marshmallow,所以这可能是一个可行的方法。

这是一个替代方案:

  • 使用 Marshmallow I/O [反|]序列化
  • 使用 marshmallow-mongoengine 从您的 Mongo 引擎模式
  • 尽可能自动地创建您的棉花糖 API 模式
  • 使用 webargs 解析参数(将 flask 请求参数注入棉花糖模式)
  • 使用 apispec 记录遵循 OpenAPI 标准的规范
  • 为了简化操作,请使用 flask-smorest 隐藏 webargs/apispec 层并提供漂亮的界面。

这个 lib 组合不像整体 flask-restplus 那样成熟和有特色,但是使用 marshmallow 很好,因为它是一个很棒的 lib 并且因为 marshmallow-mongoengine 提供的 DRYness .


µMongo 是 MongoEngine 的替代品,它基于 marshmallow,所以它就像 MongoEngine with marshmallow-mongoengine included.

它的 documentation 有一个模式来说明验证的不同阶段:API 客户端和业务对象之间,以及对象和数据库之间的 ODM。


(免责声明:marshmallow、webargs、apispec 和 flask-rest-api 维护者、µmongo、mongoengine 和 flask -mongo引擎贡献者。)