在我的情况下,我如何以正确的方式旋转代码?戈兰
几乎有两个相同的功能可以执行大致相同的事情。在这种情况下,组织代码避免重复的正确方法是什么? httpgetter()函数访问云平台API并获取JSON响应,然后我在另一个函数中对其进行解析,并基于它从模板中形成Terraform。 getToken()函数几乎做同一件事,只需获得一个令牌,然后在httpgetter()函数中使用它。
var accessToken = getToken()
func httpGetter(method, url string) (*http.Response, []byte) {
client := &http.Client{}
req, err := http.NewRequest(method, url, nil)
if err != nil {
fmt.Println(err)
}
req.Header.Add("Accept", "application/json;version=35.0")
req.Header.Add("Authorization", "Bearer "+accessToken)
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
}
return res, body
}
func getToken() string {
url := "https://cloud-platform-api.com/api/sessions"
method := "POST"
client := &http.Client{}
req, err := http.NewRequest(method, url, nil)
if err != nil {
fmt.Println(err)
}
req.Header.Add("Accept", "application/*+xml;version=35.0")
req.Header.Add("Authorization", "Basic <auth-hash>")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
}
defer res.Body.Close()
if err != nil {
fmt.Println(err)
}
accessToken := res.Header.Get("x-vmware-vcloud-access-token")
return accessToken
}
There are almost two identical functions that do approximately the same thing. What would be the right way to organize the code to avoid repetition in this case? The httpGetter() function accesses cloud platform API and gets JSON response, which I then parsed in another function and based on it I form terraform manifest from the template. The getToken() function does almost the same thing, just gets a token, which is then used in the httpGetter() function.
var accessToken = getToken()
func httpGetter(method, url string) (*http.Response, []byte) {
client := &http.Client{}
req, err := http.NewRequest(method, url, nil)
if err != nil {
fmt.Println(err)
}
req.Header.Add("Accept", "application/json;version=35.0")
req.Header.Add("Authorization", "Bearer "+accessToken)
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
}
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
if err != nil {
fmt.Println(err)
}
return res, body
}
func getToken() string {
url := "https://cloud-platform-api.com/api/sessions"
method := "POST"
client := &http.Client{}
req, err := http.NewRequest(method, url, nil)
if err != nil {
fmt.Println(err)
}
req.Header.Add("Accept", "application/*+xml;version=35.0")
req.Header.Add("Authorization", "Basic <auth-hash>")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
}
defer res.Body.Close()
if err != nil {
fmt.Println(err)
}
accessToken := res.Header.Get("x-vmware-vcloud-access-token")
return accessToken
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,如果您知道该方法是getter,则不需要传递方法参数,因此签名将变成以下类似。另外,您已经返回
*http.Response
回到呼叫者,现在将是呼叫者决定如何使用响应 +呼叫者在http中该怎么办呼叫失败,请返回错误,让呼叫者决定。现在您还需要
post
带有身体的方法(在某些情况下),因此现在有另一个功能来管理签名并具有通用代码,您可以拥有一种私人方法,该方法将仅在此文件中使用或您 揭示该方法(由您决定)
还可以使用这两种方法的呼叫来
,现在您可以使用它来通过呼叫者来传递auth令牌,例如:
对于您不需要传递标题的情况,你可以做
First thing first if you know the method is a getter then you don't need to pass the method param so the signature would become something like below. Also, you are already returning a
*http.Response
back to the caller now it will be the callers decision on what to do with the response + the caller should decide what to do in case of if the HTTP call fails so return error and let the caller decide.Now you also want
POST
method with body (in some cases) so have another functionNow to manage both signature and have a common code you could have a private method that will be just used in this file or you could also expose that method (it is up to you)
Using this your call from the two methods would look like
Now you can use this to pass the auth token from the caller like:
and for cases where you don't need to pass header, you can do