亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

使用 Golang 從 PUT/PATCH 忽略 JSON 有效負載中不需要的字段的最佳方法是什么?

使用 Golang 從 PUT/PATCH 忽略 JSON 有效負載中不需要的字段的最佳方法是什么?

Go
素胚勾勒不出你 2021-09-10 18:02:59
我有一種情況,使用我們的 API 的人需要對我的資源進行部分更新。我知道 HTTP 明確指定這是一個 PATCH 操作,即使我們這邊的人習慣于為此發送 PUT 請求,這就是遺留代碼的構建方式。作為示例,想象一下簡單的以下結構:type Person struct {    Name string    Age int    Address string}在 POST 請求中,我將提供包含所有三個值(名稱、年齡、地址)的有效負載,并在我的 Golang 后端相應地驗證它們。簡單的。但是,對于 PUT/PATCH 請求,我們知道,例如,aname永遠不會改變。但是如果我想更改age,那么我只需發送一個包含新的 JSON 有效負載age:PUT /person/1 {age:30}現在我的真正問題是:防止name我們的 API 的使用者發送包含該name字段的 JSON 有效負載時有意或無意地使用/更新的最佳實踐是什么?例子:PUT /person/1 {name:"New Name", age:35} 我想到的但實際上并不喜歡它們的可能解決方案是:在我的validator方法中,我要么強行刪除不需要的字段,要么name回復一條錯誤消息,說這name是不允許的。創建一個 DTO 對象/結構,它幾乎是我的Person結構的擴展,然后將我的 JSON 有效負載解組到其中,例如type PersonPut struct {    Age int    Address string}在我看來,這會添加不必要的額外代碼和邏輯來抽象問題,但是我沒有看到任何其他優雅的解決方案。老實說,我不喜歡這兩種方法,我想知道你們是否遇到了同樣的問題以及如何解決它。
查看完整描述

3 回答

?
千巷貓影

TA貢獻1829條經驗 獲得超7個贊

您帶來的第一個解決方案是一個很好的解決方案。一些眾所周知的框架用于實現類似的邏輯。


例如,最新的 Rails 版本帶有一個內置的解決方案,以防止用戶在請求中添加額外的數據,從而導致服務器更新數據庫中的錯誤字段。它是一種由ActionController::Parameters類實現的白名單。


假設我們有一個如下所示的控制器類。出于本說明的目的,它包含兩個update操作。但是你不會在真正的代碼中看到它。


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' }


查看完整回答
反對 回復 2021-09-10
?
當年話下

TA貢獻1890條經驗 獲得超9個贊

如果無法寫入名稱,則無法為任何更新請求提供該名稱。如果名稱存在,我會拒絕該請求。如果我想要更寬容,我可能會考慮僅在 name 與當前 name 不同時拒絕請求。

我不會默默地忽略與當前名稱不同的名稱。


查看完整回答
反對 回復 2021-09-10
?
holdtom

TA貢獻1805條經驗 獲得超10個贊

這可以通過將 JSON 主體解碼為map[string]json.RawMessage第一個來解決。該json.RawMessage類型對于延遲實際解碼很有用。之后,可以在map[string]json.RawMessage地圖上應用白名單,忽略不需要的屬性,只解碼json.RawMessage我們想要保留的屬性。

可以使用reflect包自動將列入白名單的 JSON 主體解碼為結構體的過程;可以在此處找到示例實現。


查看完整回答
反對 回復 2021-09-10
  • 3 回答
  • 0 關注
  • 448 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號