• 基于gin的golang web开发:服务间调用


    微服务开发中服务间调用的主流方式有两种HTTP、RPC,HTTP相对来说比较简单。本文将使用 Resty 包来实现基于HTTP的微服务调用。

    Resty简介

    Resty 是一个简单的HTTP和REST客户端工具包,简单是指使用上非常简单。Resty在使用简单的基础上提供了非常强大的功能,涉及到HTTP客户端的方方面面,可以满足我们日常开发使用的大部分需求。

    go get安装

    go get github.com/go-resty/resty/v2
    

    使用Resty提交HTTP请求

    client := resty.New()
    
    resp, err := client.R().
        Get("https://httpbin.org/get")
    
    resp, err := client.R().
          SetQueryParams(map[string]string{
              "page_no": "1",
              "limit": "20",
              "sort":"name",
              "order": "asc",
              "random":strconv.FormatInt(time.Now().Unix(), 10),
          }).
          SetHeader("Accept", "application/json").
          SetAuthToken("BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F").
          Get("/search_result")
    
    resp, err := client.R().
          SetQueryString("productId=232&template=fresh-sample&cat=resty&source=google&kw=buy a lot more").
          SetHeader("Accept", "application/json").
          SetAuthToken("BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F").
          Get("/show_product")
    
    resp, err := client.R().
          SetResult(AuthToken{}).
          ForceContentType("application/json").
          Get("v2/alpine/manifests/latest")
    

    以上代码演示了HTTP GET请求,Resty提供SetQueryParams方法设置请求的查询字符串,使用SetQueryParams
    方法我们可以动态的修改请求参数。SetQueryString也可以设置请求的查询字符串,如果参数中有变量的话,需要拼接字符串。SetHeader设置请求的HTTP头,以上代码设置了Accept属性。SetAuthToken设置授权信息,本质上还是设置HTTP头,以上例子中HTTP头会附加Authorization: Bearer BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F授权属性。SetResult设置返回值的类型,Resty自动解析json通过resp.Result().(*AuthToken)获取。

    下面来看一下POST请求

    client := resty.New()
    
    resp, err := client.R().
          SetBody(User{Username: "testuser", Password: "testpass"}).
          SetResult(&AuthSuccess{}).
          SetError(&AuthError{}).
          Post("https://myapp.com/login")
    
    resp, err := client.R().
          SetBody(map[string]interface{}{"username": "testuser", "password": "testpass"}).
          SetResult(&AuthSuccess{}).
          SetError(&AuthError{}).
          Post("https://myapp.com/login")
    
    resp, err := client.R().
          SetHeader("Content-Type", "application/json").
          SetBody(`{"username":"testuser", "password":"testpass"}`).
          SetResult(&AuthSuccess{}).
          Post("https://myapp.com/login")
    
    resp, err := client.R().
          SetHeader("Content-Type", "application/json").
          SetBody([]byte(`{"username":"testuser", "password":"testpass"}`)).
          SetResult(&AuthSuccess{}).
          Post("https://myapp.com/login")
    

    POST请求的代码和GET请求类似,只是最后调用了Post方法。POST请求可以附带BODY,代码中使用SetBody方法设置POST BODY。SetBody参数类型为结构体或map[string]interface{}时,Resty自动附加HTTP头Content-Type: application/json,当参数为string或[]byte类型时由于很难推断内容的类型,所以需要手动设置Content-Type请求头。SetBody还支持其他类型的参数,例如上传文件时可能会用到的io.Reader。SetError设置HTTP状态码为4XX或5XX等错误时返回的数据类型。

    Resty 也提供了发起其他请求的方法,发起PUT请求和发起POST请求代码上只需要把最后的Post改成Put方法。其他没有差别,一样可以调用SetBodySetError等方法。代码如下

    client := resty.New()
    
    resp, err := client.R().
          SetBody(Article{
            Title: "go-resty",
            Content: "This is my article content, oh ya!",
            Author: "Jeevanandam M",
            Tags: []string{"article", "sample", "resty"},
          }).
          SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
          SetError(&Error{}).
          Put("https://myapp.com/article/1234")
    

    PATCH,DELETE,HEAD,OPTIONS请求也是一样的,Resty为我们提供了一致的方式发起不同请求。

    高级应用

    代理

    使用Resty作为HTTP客户端使用的话,添加代理似乎是一个常见的需求。Resty提供了SetProxy方法为请求添加代理,还可以调用RemoveProxy移除代理。代码如下:

    client := resty.New()
    
    client.SetProxy("http://proxyserver:8888")
    
    client.RemoveProxy()
    

    重试

    client := resty.New()
    
    client.
        SetRetryCount(3).
        SetRetryWaitTime(5 * time.Second).
        SetRetryMaxWaitTime(20 * time.Second).
        SetRetryAfter(func(client *resty.Client, resp *resty.Response) (time.Duration, error) {
            return 0, errors.New("quota exceeded")
        })
    
    client.AddRetryCondition(
        func(r *resty.Response) (bool, error) {
            return r.StatusCode() == http.StatusTooManyRequests
        },
    )
    

    由于网络抖动带来的接口稳定性的问题Resty提供了重试功能来解决。以上代码我们可以看到SetRetryCount设置重试次数,SetRetryWaitTimeSetRetryMaxWaitTime设置等待时间。SetRetryAfter是一个重试后的回调方法。除此之外还可以调用AddRetryCondition设置重试的条件。

    中间件

    Resty 提供了和Gin类似的中间件特性。OnBeforeRequestOnAfterResponse回调方法,可以在请求之前和响应之后加入自定义逻辑。参数包含了resty.Client和当前请求的resty.Request对象。成功时返回nil,失败时返回error对象。

    client := resty.New()
    
    client.OnBeforeRequest(func(c *resty.Client, req *resty.Request) error {
    
        return nil
    })
    
    client.OnAfterResponse(func(c *resty.Client, resp *resty.Response) error {
    
        return nil
    })
    

    文章出处:基于gin的golang web开发:服务间调用

  • 相关阅读:
    DOM对象和JQuery对象的区别
    处理android手机html5页面中,点击text文本框无法自动获取焦点的处理方法
    ORACLE之VBO-5530无法删除用户的解决办法
    当oracle clob类型不能和group by并用,但是需要去除多列重复
    Android 4主线程访问网络
    Android: How to get Address from geolocation using Geocoder
    解决乱码的最后方法
    tomcat启动时自动运行代码
    android 组件隐蔽显示状态
    android模拟器Genymotion 连接eclipse项目
  • 原文地址:https://www.cnblogs.com/huaface/p/14108081.html
Copyright © 2020-2023  润新知