2015-01-05 33 views
0

我的應用程序會執行大量的API調用,並試圖擺脫一些重複。從概念上講以下步驟重複,每一次:摘要GET,讀取,解組邏輯

  1. 做一個GET請求
    1. 檢查錯誤
  2. 讀取響應的身體
    1. 檢查錯誤
  3. 反序列化爲目標struct
    1. 檢查錯誤
  4. 將目標結構

所有調用的唯一顯著差異是目標結構。 在代碼中,它看起來是這樣的:

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) 

我覺得這應該是可能的...

+0

我建議把你目前在中間件重複的代碼。 –

回答

0

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

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

example

+0

如此接近但迄今爲止的方式。感謝您的最終推動!順便說一句,return interace {}甚至不是必需的。 – harm

+0

寫得太快我想,甚至沒有使用我不需要的回報;) – JimB