我正在 golang 中制作一個 REST API,我想添加對過濾字段的支持,但我不知道實現它的最佳方法,假設我有這個表示Album模型的結構type Album struct { ID uint64 `json:"id"` User uint64 `json:"user"` Name string `json:"name"` CreatedDate time.Time `json:"createdDate"` Privacy string `json:"privacy"` Stars int `json:"stars"` PicturesCount int `json:"picturesCount"`}和一個返回一個實例的函數 Albumfunc GetOne(id uint64, user uint64) (Album, error) { var album Album sql := `SELECT * FROM "album" WHERE "id" = $1 AND "user" = $2;` err := models.DB.QueryRow(sql, id, user).Scan( &album.ID, &album.User, &album.Name, &album.CreatedDate, &album.Privacy, &album.Stars, &album.PicturesCount, ) return album, err}客戶要發出這樣的請求https://api.localhost.com/albums/1/?fields=id,name,privacy拋開明顯的安全問題不談,我的第一個想法是使用類似這樣的方法過濾數據庫中的字段func GetOne(id uint64, user uint64, fields string) { var album Album sql := fmt.Sprintf(`SELECT %s FROM "album" WHERE "id" = $1 AND "user" = $2;`, fields) // i don't know what to do after this}然后我想omitempty在所有字段中添加標簽并將字段設置為零值,然后再將其編碼為 JSON,這行得通嗎?哪個是更好的方法?有沒有最好的方法?我將如何實施第一種方法?謝謝你。
1 回答

郎朗坤
TA貢獻1921條經驗 獲得超9個贊
對于您的第一個提案(僅查詢請求的字段),有兩種方法(回答“這可行嗎?”和“我將如何實施第一種方法?”):
動態地創建一個(可能是匿名的)
struct
并使用encoding/json
.實現一個包裝器,它將
*database/sql.Rows
您從查詢中返回的內容轉換為 JSON。
對于方法(1.),您將需要以某種方式struct
為原始屬性的任何組合創建s struct
。由于reflect
無法在運行時創建新的結構類型,您唯一的機會就是在編譯時生成它們。組合爆炸會使你的二進制文件膨脹,所以不要那樣做。
方法(2.)應謹慎處理,只能作為最后的手段。獲取請求字段列表并使用從 DB 獲得的值寫出 JSON 聽起來很簡單,并且不涉及反射。但是,您的解決方案將(很可能)比encoding/json
.
在閱讀您的問題時,我也考慮過使用json:"omitempty"
struct 標簽。我認為這是更可取的解決方案。它既不涉及元編程也不涉及編寫自己的 JSON 編碼器,這是一件好事。請注意在某些字段丟失的情況下的影響(客戶端可能必須考慮這一點)。您可以始終查詢所有屬性并使用反射覆蓋不需要的屬性。
最后,上述所有解決方案都是次優的,最好的解決方案是根本不實現該功能。我希望您有充分的理由使屬性可變,我很高興根據您的解釋進一步澄清我的答案。但是,如果資源的其中一個屬性太大,它可能應該是子資源。
- 1 回答
- 0 關注
- 204 瀏覽
添加回答
舉報
0/150
提交
取消