duanmi4379 2017-07-03 20:58
浏览 90

在Golang中处理网址中的动态参数

currently am working on an API Rest in Golang. I have the process to CRUD all the tables. Now someone is asking me to develop an endpoint to search in one of that tables based on the parameters send in the URL. Let's say that this is my struct for that table:

type Media struct {
    ID                         uint       
    Key                   string     
    RecordKey           string     
    RecordID            string     
    SystemMediaKey      string          
    MediaObjectID       string   
    ChangedByID         string   
    ChangedByKey        string   
    MediaCategory              string   
    MimeType                   string   
    ShortDescription           string   
    LongDescription            string   
    EntryTimestamp             time.Time
    ModificationTimestamp      time.Time  
    DeletedAtTimestamp         *time.Time 
    MediaModificationTimestamp time.Time
    MediaURL                   string   
    MediaHTML                  string   
    Order                      int      
    Group                      string   
    Width                      int      
    Height                     int      
    ImageSize                  string   
    ResourceName               string  
    ClassName                  string 
    Permission                 *string
    MediaStatus                string
}

Now, he can send me all or some of that fields in the URL, the I need to assign that values to my struct to be able to search in the database based on the data assigned to the object.

I am using Gorm to handle everything with the database, gorilla/schema to assign the values on the POST requests and the Julien Schmidt Router. Now,my questions are:

  1. What should I configure in the route to accept dynamic parameters?
  2. How can I assign the values that comes in the URL to the a type Media object? Thank you!
  • 写回答

2条回答 默认 最新

  • dreamfly0514 2017-07-03 22:04
    关注

    You could use the reflect package to iterate over the fields and set them by name. Be aware that the reflect package is arduous to use and comes with some dangers of panics if not used properly.

    Also be aware that url.Values.Get only returns the first value (see https://godoc.org/net/url#Values.Get for details)

    EDIT: I added code to account for the pointers in the struct. They are handled differently.

    https://play.golang.org/p/AO4lYx7xka

    package main
    
    import (
        "fmt"
        "net/url"
        "reflect"
        "time"
    )
    
    type Media struct {
        ID                         uint
        Key                        string
        RecordKey                  string
        RecordID                   string
        SystemMediaKey             string
        MediaObjectID              string
        ChangedByID                string
        ChangedByKey               string
        MediaCategory              string
        MimeType                   string
        ShortDescription           string
        LongDescription            string
        EntryTimestamp             time.Time
        ModificationTimestamp      time.Time
        DeletedAtTimestamp         *time.Time
        MediaModificationTimestamp time.Time
        MediaURL                   string
        MediaHTML                  string
        Order                      int
        Group                      string
        Width                      int
        Height                     int
        ImageSize                  string
        ResourceName               string
        ClassName                  string
        Permission                 *string
        MediaStatus                string
    }
    
    func main() {
    
        testUrl := "www.example.com/test?MimeType=themimetype&Key=thekey&Permission=admin"
    
        u, err := url.Parse(testUrl)
        if err != nil {
            fmt.Println(err)
            return
        }
    
        params := u.Query()
    
        media := &Media{}
    
        val := reflect.ValueOf(media)
    
        for i := 0; i < val.Elem().NumField(); i++ {
            // get the reflect.StructField so we can get the Name
            f := val.Elem().Type().Field(i)
    
            // check if URL.Values contains the field
            if v := params.Get(f.Name); v != "" {
                // get the reflect.Value associated with the Field
                field := val.Elem().FieldByName(f.Name)
    
                kind := field.Kind()
    
                // you must switch for each reflect.Kind (associated with the type in your struct)
                // so you know which Set... method to call
                switch kind {
                case reflect.String:
                    field.SetString(v)
                case reflect.Ptr:
                    // pointers are a special case that must be handled manually unfortunately.
                    // because they default to nil, calling Elem() won't reveal the underlying type
                    // so you must simply string match the struct values that are pointers.
                    switch f.Name {
                    case "Permission":
                        newVal := reflect.New(reflect.TypeOf(v))
                        newVal.Elem().SetString(v)
                        field.Set(newVal.Elem().Addr())
                    case "DeletedAtTimestamp":
                    }
                }
    
            }
        }
    
        fmt.Printf("%#v
    ", media)
        fmt.Println(*media.Permission)
    }
    
    评论

报告相同问题?

悬赏问题

  • ¥15 划分vlan后不通了
  • ¥15 GDI处理通道视频时总是带有白色锯齿
  • ¥20 用雷电模拟器安装百达屋apk一直闪退
  • ¥15 算能科技20240506咨询(拒绝大模型回答)
  • ¥15 自适应 AR 模型 参数估计Matlab程序
  • ¥100 角动量包络面如何用MATLAB绘制
  • ¥15 merge函数占用内存过大
  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大
  • ¥15 单片机无法进入HAL_TIM_PWM_PulseFinishedCallback回调函数