Изучаем Go – Снова о модульном проектировании
Снова создаем модули
Ранее мы создали нашу самую первую модульную версию пакета mailgunner. На этот раз давайте посмотрим, что нам нужно сделать в новой версии - мы немного изменим код, обновим readme, а затем создадим новую версию.
Ditch http.DefaultClient, Sort of
Одна из проблем, связанных с использованием http.DefaultClient, заключается в том, что он в основном, как говорится, как клиент barebones, не устанавливает каких-либо разумных значений по умолчанию. Что же делать, если кому-то нужно сделать прокси-запрос? Или установить таймаут? Реализация таких задач с использованием нашего предыдущего модуля перестает быть тривиальной задачей. Именно поэтому нам нужно организовать взаимодействие так, чтобы наш модуль не зависел от этого. Итак, мы собираемся немного расширить его возможности, чтобы мы смогли перейти на собственный клиент. Мы изменили функцию New(), я покажу здесь, что мы именно поменяли, а в репозитории или предыдущей статье, вы сможете увидеть полный код.
Изначально, наша функция была очень простой и просто возвращала структуру, которая содержала две строки и http.DefaultClient.
type MgClient struct { MgAPIURL string MgAPIKey string Client *http.Client } func New(apiurl, apikey string) MgClient { return MgClient{ apiurl, apikey, http.DefaultClient, } }
Как я говорил, мы не будем изменять саму структуру - мы просто обновим метод New(), чтобы получать другой параметр. Заметьте, теперь мы возвращаем указатель на MgClient, который, вероятно, должен был быть в предыдущей версии. Но мы же пока только тренируемся и учимся). Наш новый параметр, с умным именем, client примет * http.Client - мы еще немного рассмотрим, как нужно правильно его использовать.
func New(apiurl, apikey string, client *http.Client) *MgClient { if client == nil { client = http.DefaultClient } return &MgClient{ apiurl, apikey, client, } }
Если кто-то используя модуль, отказывается создавать собственный клиент и вместо него передает nil, мы вернемся к использованию http.DefaultClient.
mgc := mailgunner.New(apiurl, mgKey, nil)
Настраиваемый клиент
Итак, как же мы можем использовать наш кастомный клиент? На самом деле довольно легко! Перед вызовом метода New() мы создадим новую переменную cc и передадим ей & http.Client{} со временем ожидания (таймаутом) в 10 секунд.
cc := &http.Client{ Timeout: time.Second * 10, }
Как раз таки это станет блестящим третьем параметром передаваемым нашим необычным клиентом в метод New().
mgc := mailgunner.New(apiurl, mgKey, cc)
Все остальное будет работать совершенно так же как и ранее.
v2 версия
Мы все еще не совсем готовы выпустить новый модуль, т.к, во-первых, нам придется обновить файл readme, который для краткости я не буду здесь указывать. Затем нам нужно обновить файл go.mod, чтобы указать, что мы переходим к новой версии. С того момента, как мы изменили сигнатуру функции New(), я решил, что это будет наша основная версия, а новый go.mod просто добавил "v2" к ней.
module github.com/shindakun/mailgunner/v2
Пробежимся по командам Git, чтобы отправить все на Github. Начнем с создания ветки v2 (которую вы, скорее всего, создадите прежде, чем начнете вносить изменения в код, хотя я этого не делал), добавим наши изменения, которые затем будут зафиксированы в этой ветке.
git checkout -b v2 git add . git commit -m "Updated New() to take http.Client so we don't have to rely on http.DefaultClient"
Все идет по плану, а теперь мы перенесем нашу ветку в remote, затем отметим и вставим метки (tags).
git push --set-upstream origin v2 git tag v2.0.0 git push --tags origin v2
Теперь любой желающий может просто импортировать модуль с помощью /v2, запустить go build и с удовольствием работать!
➜ GO111MODULE=on go build -v github.com/shindakun/mailgunner/v2 github.com/shindakun/mailgunner/v2/example
В продолжении
Я все еще думаю о том, чтобы сделать серию постов о создание «devlog» на своем собственном домене. Мне еще нужно решить, как именно это сделать.
До скорого ...
Другие статьи из цикла:
- Изучаем Go - создание загрузчика (часть 1)
- Изучаем Go - создание загрузчика (часть 2)
- Изучаем Go - создание загрузчика (часть 3)
- Изучаем Go - создание загрузчика (часть 4)
- Изучаем Go - создание загрузчика (часть 5)
- Изучаем Go - Использование REST API
- Изучаем Go - Продолжаем работать с REST API
- Изучаем Go - Отправка REST-запросов
- Изучаем Go - Используем REST API в паре с шаблонами проектирования
- Изучаем Go - Повторная отправка электронной почты через API
- Изучаем Go – Наконец-то используем модули
- Изучаем Go - Давайте станем модульными снова!
- Изучаем Go - Сборка DevLog Часть 01
- Изучаем Go - Сборка DevLog Часть 02
- Изучаем Go - Сборка DevLog Часть 03
- Изучаем Go - Сборка DevLog Часть 04