jjzjj

go - HTTP批量从多个API获取并保存到结构

coder 2024-07-07 原文

我有以下函数可用于获取 URL 并将数据返回到接口(interface)(例如 struct/int/whatever):

var httpClient = &http.Client{Timeout: 10 * time.Second}

func getURLToTarget(url string, target interface{}) error {
    req, err := httpClient.Get(url)
    if err != nil {
        return err
    }
    defer req.Body.Close()
    return json.NewDecoder(req.Body).Decode(target)
}

然后我有几个看起来像这样的函数:

func GetCustomerByID(APIKey, cusID string) {
  cus := new(Customer)
  getURLToTarget(fmt.Sprintf("http://someurl.com/%s/customerbyid/:%s", APIKey, cusID), &cus)
}

在这种情况下会将 json 响应保存到这样的结构中:

type Customer struct {
  Name string
  Email string
  Address string
}

现在我的问题是,如何让所有这些 http 请求在我运行时同时执行:

func main() {
  apikey := "some api key"
  GetCustomerByID(apikey, "43279843")
  GetCustomerDiscounts(apikey, "43279843")
  GetProductByID(apikey, "32124")
}

我很确定我需要使用 channel ,但我不知道如何...任何帮助将不胜感激

最佳答案

实现这一目标的方法有很多种,具体取决于您需要发生什么。

最基本的是使用 goroutines 和 wg.WaitGroup 并行/并发地进行 http 调用,并在退出程序之前等待所有调用完成。例如:

func main() {
  apikey := "some api key"

  var wg sync.WaitGroup
  wg.Add(3)

  go func() {
    GetCustomerByID(apikey, "43279843")
    wg.Done()
  }()

  go func() {
    GetCustomerDiscounts(apikey, "43279843")
    wg.Done()
  }()

  go func() {
    GetProductByID(apikey, "32124")
    wg.Done()
  }()

  wg.Wait()
}

如果您想检查每个 http 调用的结果,另一种方法是使用 go channel。例如:

func GetCustomerByID(APIKey, cusID string) Customer {
  cus := new(Customer)
  getURLToTarget(fmt.Sprintf("http://someurl.com/%s/customerbyid/:%s", APIKey, cusID), &cus)
  return cus
}

func main() {
  apikey := "some api key"

  c := make(chan Customer, 3)

  go func() {
    cus := GetCustomerByID(apikey, "43279843")
    c <- cus
  }()

  go func() {
    cus := GetCustomerDiscounts(apikey, "43279843")
    c <- cus
  }()

  go func() {
    cus := GetProductByID(apikey, "32124")
    c <- cus
  }()

  // Print the result
  var i int
  for cus := range c {
    fmt.Printf("%#v\n", cus)
    i++

    if i == 3 {
      break
    }
  }
}

关于go - HTTP批量从多个API获取并保存到结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44017927/

有关go - HTTP批量从多个API获取并保存到结构的更多相关文章

  1. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  2. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  3. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  4. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  5. ruby - 如何模拟 Net::HTTP::Post? - 2

    是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

  6. ruby - 多个属性的 update_column 方法 - 2

    我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2

  7. ruby-on-rails - 在 ruby​​ .gemspec 文件中,如何指定依赖项的多个版本? - 2

    我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这

  8. ruby - 简单获取法拉第超时 - 2

    有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url

  9. ruby-on-rails - ActionController::RoutingError: 未初始化常量 Api::V1::ApiController - 2

    我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc

  10. ruby - 从 Ruby 中的主机名获取 IP 地址 - 2

    我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge

随机推荐