举例来说,想象一下简单的结构:
type Person struct { Name string Age int Address string }
在POST请求中,我将提供具有所有三个值(名称,年龄,地址)的有效负载,并在我的Golang后端上相应地验证它们.简单.
但是,在PUT / PATCH请求中,我们知道,例如,名称永远不会改变.但是说我想改变年龄,那么我只需发送一个包含新时代的JSON有效负载:
PUT /person/1 {age:30}
现在我真正的问题:@H_502_12@如果我们的API的消费者发送包含名称字段的JSON有效负载,则有意或无意修改名称的最佳做法是什么?
例:
PUT /person/1 {name:"New Name",age:35}
我想到的可能的解决方案,但我实际上并不喜欢它们,是:
>在我的验证器方法上,我会强行删除不需要的字段名称,或者回复一条错误消息,说明该名称是不允许的.@H_502_12@>创建一个DTO对象/结构,它几乎是我的Person结构的扩展,然后将我的JSON有效负载解组到其中,例如
type PersonPut struct {@H_502_12@年龄int@H_502_12@地址字符串@H_502_12@}
在我看来,这将添加不必要的额外代码和逻辑来抽象问题,但我没有看到任何其他优雅的解决方案.
老实说,我不喜欢这两种方法,我想知道你们是否面临同样的问题,以及你们是如何解决它的.
谢谢!
例如,最新的Rails版本附带内置解决方案,以防止用户在请求中添加额外数据,从而导致服务器更新数据库中的错误字段.它是ActionController :: Parameters类实现的一种白名单.
我们假设我们有一个控制器类如下所示.出于此说明的目的,它包含两个更新操作.但你不会在实际代码中看到它.
class PeopleController < ActionController::Base # 1st version - Unsafe,it will rise an exception. Don't do it def update person = current_account.people.find(params[:id]) person.update!(params[:person]) redirect_to person end # 2nd version - Updates only permitted parameters def update person = current_account.people.find(params[:id]) person.update!(person_params) # call to person_params method redirect_to person end private def person_params params.require(:person).permit(:name,:age) end end
由于第二个版本仅允许允许的值,因此它将阻止用户更改有效负载并发送包含新密码值的JSON:
{ name: "acme",age: 25,password: 'account-hacked' }
有关更多详细信息,请参阅Rails文档:Action Controller Overview和ActionController::Parameters