Мое приложение выполняет множество вызовов API, и я пытаюсь избавиться от некоторого дублирования, окружающего это. Концептуально следующие шаги повторяются каждый раз, когда:Аннотация Получите, прочитайте, немаршалируйте логику
- Do запрашивайте ПОЛУЧИТЬ
- Проверка на наличие ошибок
- Прочитайте тело ответа
- Проверка на наличие ошибок
- Deserialize to target struct
- Проверка на наличие ошибок
- Верните целевой структура
Единственное существенное различие между всеми вызовами является целевой структурой. В коде это выглядит примерно так:
func getUsers() ([]User, error) {
resp, err := http.Get(someUrl)
if err != nil {
return nil, err
}
if resp.StatusCode != 200 {
return nil, errors.New("Search return non 200 status code")
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var users []User // This is the only real difference!
err = json.Unmarshal(body, &users)
if err != nil {
return nil, err
}
return users, nil
}
Я хотел бы сделать что-то вроде getUsers(url, users)
и getProjects(url, projects)
.
Я пытался с помощью функции, которая принимает interface{}
и брось позже к нужному типу снова, но безрезультатно:
func request(url string, target interface{}) (interface{}, error) {
// do all the same logic as above. Except:
err = json.Unmarshal(body, &target)
// ...
return target, nil
}
, а затем сделать что-то вроде:
var users []User
result, err := request(url, users)
v, ok := result.([]User)
У меня такое чувство, что это должно быть возможно ...
Я рекомендовал бы поставить код, который вы в настоящее время дублируется в ППО. –