Use type parameters to eliminate code duplication:
// GetJson decodes the resource at url to T and returns the result.
func GetJson[T any](url string) (T, error) {
req, err := http.NewRequest("GET", url, nil)
// commented out error handling
resp, err := myClient.Do(req)
// commented out error handling
defer resp.Body.Close()
var target T
err = json.NewDecoder(resp.Body).Decode(target)
// commented out error handling
return target, err
}
// GetJsons decodes each resource at urls to a T and returns
// a slice of the results.
func GetJsons[T any](urls []string) ([]T, []error) {
errors := make([]error, len(urls))
targets := make([]T, len(urls))
var wg sync.WaitGroup
wg.Add(len(urls))
for i, url := range urls {
go func() {
defer wg.Done()
targets[i], errors[i] = GetJson[T](url)
}()
}
wg.Wait()
return targets, errors
}
Example use:
hashmaps, errors := GetJsons[Map](urls)