从多个API的HTTP批处理获取并保存到结构

I have the following function that I use to get a URL and return the data to an interface (e.g. 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)
}

then I have several functions that look like this:

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

which in this case will save the json response into a struct like this:

type Customer struct {
  Name string
  Email string
  Address string
}

Now my question is, how can I make all these http requests perform simultaneously when I run:

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

I am pretty sure I need to use channels but I can't figure out how.. any help would be much appreciated

There are many ways to achieve this and it's based on what you need to happen.

The basic one is to use goroutines and wg.WaitGroup to do http call in parallel/concurrent and wait for all of it to finish before exiting the program. For example:

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()
}

Another approach is to use go channel if you want to inspect the result of each http call. For example:

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
", cus)
    i++

    if i == 3 {
      break
    }
  }
}