我正在迁移最初用 Python 编写的 API。
Python API 允许您以camelCase 或snake_case 形式发送请求,如下所示:
这是允许的
{
"someInput": "nice"
}
这是允许的
{
"some_input": "nice"
}
这是使用一个很棒的 Python 库完成的:Pydantic
from pydantic import BaseModel
def to_camel(string):
words = string.split('_')
return words[0] + ''.join(word.capitalize() for word in words[1:])
class InputModel(BaseModel):
some_input: str
class Config:
alias_generator = to_camel
allow_population_by_field_name = True
这允许通过别名(someInput)或字段名称(some_input)创建InputModel。
我想在 Go 中做相同或等效的事情。我正在使用杜松子酒:
func Routes(router *gin.Engine) {
v1 := router.Group("/v1")
{
v1.POST("/shipments", controllers.ShipmentCreator)
}
}
func ShipmentCreator(ctx *gin.Context) {
ResponseController := new(internal.OutputModel)
var body domain.ShipmentsInputModel
if err := ctx.BindJSON(&body); err != nil {
fmt.Println(err)
}
validate := validator.New()
err := validate.Struct(body)
if err != nil {
var validationErrors validator.ValidationErrors
errors.As(err, &validationErrors)
for _, validationError := range validationErrors {
ResponseController.AddError(internal.ErrorsModel{
Parameter: validationError.Field(),
Message: validationError.Error(),
})
}
ctx.JSON(http.StatusBadRequest, ResponseController)
return
}
我的输入结构看起来像这样:
type ShipmentsInputModel struct {
LotId string `json:"lotId" tag:"lot_id" alias:"lot_id" validate:"required"`
}
当我的输入是:
时,这不起作用
{
"lot_id": "someLotId"
}
它返回:
“message”: “Key: ‘ShipmentsInputModel.LotId’ Error:Field validation for ‘LotId’ failed on the ‘required’ tag”,
我怎样才能同时接受camelCase和snake_case?
在 Go 中,您无法为单个结构体字段同时提供两个 JSON 标签。 JSON 标签使用单个字符串指定,它们用于定义应如何对字段进行封送(序列化为 JSON)或取消封送(从 JSON 反序列化)。您不能直接为结构中的单个字段指定多个标签。
如果您需要在 JSON 输出中支持 CamelCase 和 SnakeCase,您通常必须为结构字段选择一种一致的命名约定,然后为所有字段使用适当的 JSON 标记。
有一种巧妙的方法可以做到这一点。我希望这会有所帮助。
package main
import (
“encoding/json”
“fmt”
)
type ShipmentsInputModel struct {
LotID
}
type LotID struct {
LotId string `json:”lotId,omitempty”`
Lot_ID string `json:”lot_id,omitempty”`
}
func (s *ShipmentsInputModel) setLodID(id string) {
s.LotId = id
s.Lot_ID = id
}
func main() {
shipment := ShipmentsInputModel{}
shipment.setLodID(“someLotID”)
// Convert struct to JSON
jsonData, err := json.Marshal(shipment)
if err != nil {
fmt.Println(“Error:”, err)
return
}
// prints: {“lotId”:”someLotID”,”lot_id”:”someLotID”}
fmt.Println(string(jsonData))
}
如果您发现该资源为电子书等存在侵权的资源或对该资源描述不正确等,可点击“私信”按钮向作者进行反馈;如作者无回复可进行平台仲裁,我们会在第一时间进行处理!
加入交流群
请使用微信扫一扫!