使用Colander验证PATCH请求

3 投票
1 回答
663 浏览
提问于 2025-04-18 09:40

编辑:我最初的问题是关于PUT请求的,基于thecoshman提供的回答,我已经将其改为PATCH请求。

我正在使用cornice开发一个RESTful网络服务,最近发现了colander。我的问题与PATCH请求有关。我现在知道PUT请求应该包含完整的记录,但PATCH请求就不一定了。我可以使用colander来验证附加在PATCH请求上的json数据吗?

Colander非常适合验证POST请求,因为它可以确保我的json中包含所有正确的数据,并且还会去掉多余的数据。

这是我简单的模式。

class OrganisationSchemaRecord(MappingSchema):
    orgname = SchemaNode(String())
    fullname = SchemaNode(String())
    description = SchemaNode(String(), missing=drop)

class OrganisationSchema(MappingSchema):
    organisation = OrganisationSchemaRecord()

这让我可以保持我的视图代码简单,如下所示。

@view(validators=(unique,), renderer='json', schema=OrganisationSchema)
def collection_post(self):
    """Adds a new organisation"""
    org = DBOrg(**self.request.validated['organisation'])#sqlalchemy model
    DBSession.add(org)
    return {'organisation': org}

这里的关键是schema=OrganisationSchema,它会验证请求的json内容,并根据模式把它放到self.request.validated['organisation']中。

它也和我的另一个验证器配合得很好,确保主键不会重复使用。

def unique(request):
    if 'organisation' in request.validated: #Implies a validated schema
        orgname = request.validated['organisation']['orgname']
        if DBSession.query(DBOrg).get(orgname):
            request.errors.add('url', 'orgname', 'This organisation already exists!')

但是,如果我想处理一个PATCH请求来更新fullnamedescription字段,那么验证就会失败,除非请求中也包含orgname的值,而我并不想更改这个值。

最好的解决方案是什么?我是否应该坚持要求PATCH请求包含完整有效的记录,还是定义一个不同的模式,或者我是不是漏掉了什么?

1 个回答

2

老实说,我大部分问题都跳过了,希望我没有漏掉什么重要的内容。

PUT请求应该是完整的记录吗 - 是的,绝对应该。

PUT请求会把你请求的地址上整个记录替换掉。

如果你只想修改一部分内容,应该使用PATCH(这个大家可能不太熟悉)。在使用PATCH之前,通常的做法是先用GET获取记录,修改完后再把整个记录用PUT重新发送回去。

撰写回答