Есть еще одна проблема логирования, с которой нам нужно разобраться. При просмотре файла handlers.go вы заметите, что функция обработчик home() по-прежнему записывает сообщения об ошибках с использованием стандартного логгера от Go, а не созданный нами логгер errorLog, которого нам нужно использовать.

Возникает вопрос: как сделать наш новый логгер errorLog доступным для функции home из main() ?

Премиум 👑 курс по Golang

Рекомендуем вам супер курс по Golang где собраны все материалы для качественного изучения языка. Удивите всех своими знаниями на собеседовании! 😎

Записаться на курс

Уроки, статьи и Видео

Мы публикуем в паблике ВК и Telegram качественные обучающие материалы для быстрого изучения Go. Подпишитесь на нас в ВК и в Telegram. Поддержите сообщество Go программистов.

Go в ВК Go в Telegram

В текущем виде кода, логгеры infoLog и errorLog не видны из за области видимости функции main().

У большинства веб-приложений будет несколько зависимостей, к которым их обработчики должны обращаться. Например пул соединений с базой данных, централизованные обработчики ошибок и кэши шаблонов. Однако, ответ на вопрос который нам действительно нужен, это: как сделать любую зависимость доступной нашим обработчикам?

Для этого есть несколько способов. Самый простой — просто поместить зависимости в глобальные переменные которых видно везде. В целом рекомендуется внедрять зависимости в обработчики. Это делает код более явным, менее подверженным ошибкам и более простым для модульного тестирования, чем в случае использования глобальных переменных.

Для приложений, в которых все обработчики находятся в одном пакете (как наше приложение), отличным способом внедрения зависимостей будет их размещение в структуру application.

Ниже мы продемонстрируем всё на примере.

Откройте файл main.go и создайте новую структуру application следующим образом:

Затем в файле handlers.go обновим обработчик home() так, чтобы ему стали доступны поля из структуры application, для этого он должен стать частью этой структуры.

Если данная тема кажется запутанной, то советую ознакомиться методами в golang из нашего курса по изучению go.

Обновляем файл main.go в котором мы определяем структуру application:

Такой подход может показаться немного сложным и запутанным, особенно когда альтернативой является простое создание глобальных переменных логгеров infoLog и errorLog. По мере того, как приложение будет расти, наши обработчики будут требовать больше зависимостей. Тогда мы и увидим всю прелесть паттерна Dependency Injection.

Тестирование логгеров в Golang

Давайте попробуем специально создать ошибку в наше веб-приложение.

Откройте терминал и переименуйте ui/html/home.page.tmpl на ui/html/home.page.bak.Теперь при запуске веб-приложения и создании HTTP-запроса к домашней страницы, результатом будет ошибка, потому что файл ui/html/home.page.tmpl больше не существует.

Попробуйте сделать изменение:

Затем, запустите приложение и выполните запрос на http://127.0.0.1:4000. В браузере вы должны получить HTTP ответ Внутренняя ошибка сервера, а также соответствующее сообщение об ошибке в терминале, наподобие следующего:

Логирование ошибок в Golang

Обратите внимание, что у сообщения об ошибке теперь есть префикс ERROR она была сгенерирована на 29-й строки файла handlers.go. Это наглядно демонстрирует, что созданный нами логгер errorLog передается обработчику home() в качестве зависимости и работает как и ожидалось.

Оставьте пока преднамеренную ошибку с несуществующим файлом шаблона home.page.tmpl  — она нам понадобится в следующем уроке.

Замыкания для внедрения зависимостей

Паттерн, который мы используем для внедрения зависимостей, не будет работать, если обработчики распределены по нескольким пакетам. В этом случае, альтернативным подходом будет создание пакета config, который экспортирует структуру Application. К примеру:

Вы можете найти более подробный пример использования паттерна замыкания ознакомившись со статьей: Замыкания и анонимные функции

Скачать исходный код

На данный момент, если вы запустите код веб-приложения, то оно будет работать, но возникнет ошибка при заходе на главную страницу. Если вы прошли урок из этой статьи, то вы должны понимать, что мы специально её оставили для будущего урока.

Скачать: snippetbox-12.zip