2016-12-30 104 views
2

我正在實現一個REST API的Go包裝器。它基本上解析JSON並且應該返回適​​當的結構類型。我發現自己做了很多這樣的:如何讓此Go代碼更幹?

// GetBlueprintDetails returns details about a blueprint 
func (c *Client) GetBlueprintDetails(projectID string, blueprintID string) (*BlueprintDetails, *APIError) { 
    path := fmt.Sprintf("projects/%s/blueprints/%s", projectID, blueprintID) 
    res, err := c.Request("GET", path, nil, nil) 
    if err != nil { 
     return nil, err 
    } 
    var ret BlueprintDetails 
    e := json.Unmarshal(res.Body, &ret) 
    if e != nil { 
     return nil, &APIError{Error: &e} 
    } 
    return &ret, nil 
} 

// GetProjects returns a list of projects for the user 
func (c *Client) GetProjects() (*[]Project, *APIError) { 
    res, err := c.Request("GET", "projects", nil, nil) 
    if err != nil { 
     return nil, err 
    } 
    var ret []Project 
    e := json.Unmarshal(res.Body, &ret) 
    if e != nil { 
     return nil, &APIError{Error: &e} 
    } 
    return &ret, nil 
} 

兩個功能之間的唯一區別是取消封送的結構基本類型。我知道在Go中沒有泛型,但必須有一種模式才能使其更加乾爽。

任何想法?

+0

類似的問題,我有,創建一個胖結構,解析這兩種請求類型,其他變量將是空的?你能分享「BlueprintDetails」結構嗎? –

回答

3

您可以創建一個MakeRequest函數,它的HTTP請求部分,並解組的JSON爲結構

這裏是你如何可以做到這一點,看看在MakeRequest功能

// GetBlueprintDetails returns details about a blueprint 
func (c *Client) GetBlueprintDetails(projectID string, blueprintID string) (*BlueprintDetails, *APIError) { 
    path := fmt.Sprintf("projects/%s/blueprints/%s", projectID, blueprintID) 
    bluePrintDetails = new(BlueprintDetails) 
    err := c.MakeRequest("GET", path, bluePrintDetails) 
    return bluePrintDetails, err 
} 

// GetProjects returns a list of projects for the user 
func (c *Client) GetProjects() (*[]Project, *APIError) { 
    projects = make([]Project, 0) 
    err := c.MakeRequest("GET", "project", &projects) 
    return &projects, err 
} 

func (c *Client) MakeRequest(method string, path string, response interface{}) *APIError { 
    res, err := c.Request(method, path, nil, nil) 
    if err != nil { 
     return nil, err 
    } 
    e := json.Unmarshal(res.Body, response) 
    if e != nil { 
     return &APIError{Error: &e} 
    } 
    return nil 
} 
+0

可愛!這很好。謝謝。 –

+0

@AssafLavie你能否接受並且喜歡答案如果解決了問題。對不起,#stackoverflow biginer需要一些聲譽才能在答案中看起來真實 –

+0

@Sarathsp能解釋爲什麼'((c * Client))'不使用'(c * Client)'? –