摘要GET,read,unmarshal logic away

时间:2015-01-05 15:45:34

标签: json http go

我的应用程序执行了大量的API调用,并且我试图摆脱一些重复的问题。从概念上讲,每次都重复以下步骤:

  1. 执行GET请求
    1. 检查错误
  2. 阅读回复正文
    1. 检查错误
  3. 反序列化为目标结构
    1. 检查错误
  4. 返回目标结构
  5. 所有调用之间唯一重要的区别是目标结构。 在代码中,它看起来像这样:

    func getUsers() ([]User, error) {
        resp, err := http.Get(someUrl)
        if err != nil {
            return nil, err 
        }
        if resp.StatusCode != 200 {
            return nil, errors.New("Search return non 200 status code")
        }
    
        defer resp.Body.Close()
    
        body, err := ioutil.ReadAll(resp.Body)
        if err != nil {
            return nil, err 
        }
    
        var users []User // This is the only real difference!
        err = json.Unmarshal(body, &users)
        if err != nil {
            return nil, err 
        }
    
        return users, nil 
    }
    

    我很乐意做getUsers(url, users)getProjects(url, projects)之类的事情。

    我一直在尝试使用一个interface{}的函数,然后再将其转换为正确的类型,但无济于事:

    func request(url string, target interface{}) (interface{}, error) {
         // do all the same logic as above. Except:
         err = json.Unmarshal(body, &target)
         // ...
         return target, nil
    }
    

    然后执行以下操作:

     var users []User
     result, err := request(url, users)
     v, ok := result.([]User)
    

    我觉得这应该是可能的......

1 个答案:

答案 0 :(得分:0)

不要使用interface{}的地址,它已包含解编所需的指针。

func request(url string, target interface{}) (interface{}, error) {
     // get response
     err = json.Unmarshal(body, target)
    ...

example