2016-12-30 6 views
2

私はREST APIのGoラッパーを実装しています。基本的にはJSONを解析し、適切な構造体の型を返す必要があります。私自身は、この多くのをやって見つける:このGoコードをDRYにするにはどうすればよいですか?

// 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にジェネリックがないことを知っていますが、これをDRYにするパターンが必要です。

アイデア?

+0

同様の問題は私が両方のタイプのリクエストを解析するためにfat構造体を作成すると、他の変数は空になりますか? "BlueprintDetails"構造体を共有できますか? –

答えて

3

あなたがここに

を構造体へのHTTPリクエストの一部とアンマーシャリングJSONを行いMakeRequest機能は、あなたがそれを行うことができます方法です作成することができ、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)'を使用しない理由を説明できますか? –

関連する問題