Чак Норрис не пишет код — он смотрит на него, пока он не напишется сам

Go — отличный серверный язык с надежной поддержкой пакетов, что упрощает сборку системы. Добавьте хорошую производительность во время выполнения, и у нас есть все инструменты, необходимые для создания простого, почти готового к работе веб-сервера (который, случается, передает занудные шутки Чака Норриса).

Для краткости я опустил несколько кусочков, но всю (пригодную для развертывания) кодовую базу можно найти здесь.

Строительные блоки

Веб-серверу нужны две вещи — API для взаимодействия клиентов с ним и логика для обработки того, для чего эти клиенты используют сервер. Начнем с разработки API.

Мы часто используем пакет net/http при создании веб-вещей на Go, и это не исключение — он предоставляет все необходимое для создания нашего сервера. Мы будем слушать /, но эта концепция может быть расширена для обслуживания любого подкаталога, который вы выберете.

net/http обеспечивает одновременную обработку запросов из коробки, поэтому мы можем работать эффективно, не задумываясь слишком много. Мы настраиваем наши функции на запросы к различным подкаталогам, используя http.HandleFunc, и ListenAndServe будет направлять эти запросы своим обработчикам в предоставленном port до тех пор, пока он не будет остановлен или не произойдет ошибка.

Затем мы должны настроить логику для обработки этих запросов. handleGetJoke — это место, где находится большая часть бизнес-логики этого примера.

Здесь мы должны сгенерировать имя для использования в шутке (вместо «Чак Норрис», просто чтобы было немного интереснее). Затем мы будем использовать эти имена для создания шутки и, наконец, вернем готовую шутку клиенту.

r представляет собой запрос, который мы получили от клиента, а w — это ответ, который мы генерируем для возврата.

Обратите внимание, что мы абстрагировали генерацию имен и шуток в модульные пакеты names и jokes соответственно. Создание модульных сервисов дает ряд преимуществ. Это сужает сферу ответственности, что упрощает обмен библиотеками, упрощает написание тестов, обеспечивает более совместную среду разработки и снижает когнитивную нагрузку, необходимую разработчикам для расширения или отладки службы. Было бы еще лучше, если бы эти модульные компоненты реализовали общий интерфейс, но это уже другая история.

Мы будем использовать randomuser.me для генерации имен для пакета names. Приведенная ниже суть в основном просто делает запрос API, а затем обрабатывает возвращенные данные JSON. GetNew() обрабатывает бизнес-логику, вызывая вспомогательные функции.

simplehttpget — это тонкая оболочка для использования http.Client, более подробно ее можно увидеть в полном репозитории.

Далее мы будем использовать Базу данных Чака Норриса в Интернете, чтобы создать шутку, используя имена, которые мы создали выше. Как и выше, GetNew() является точкой входа в этот пакет.

Опять же, это в основном предоставление имени, выполнение запроса API и анализ результата. Как только вы напишете несколько таких клиентов/потребителей API, вы начнете замечать некоторые общие шаблоны. Обратите внимание, что поля структуры являются общедоступными — это необходимо пакету json для маршалинга/демаршалирования данных.

Запуск сервера

Наконец-то пришло время для аттракциона main():

Поскольку мы создали этот сервер с несколькими пакетами, его запуск довольно лаконичен. Мы выбираем порт, вызываем StartServer и впадаем в панику, если получаем какие-либо ошибки (помните, как я писал, что это почти готово к работе? Скорее всего, вы захотите изящно обработать ошибку в реальном мире).

Теперь осталось открыть терминал в корне этого каталога и запустить go run main.go. Затем вы можете посетить localhost:5000 в веб-браузере, чтобы каждый раз при обновлении просматривать шутку Чака Норриса!

Если вы видите сообщение типа:

panic: Could not start client API server on port 5000: listen tcp :5000: bind: address already in use

Вероятно, у вас есть что-то еще, использующее порт 5000. Измените константу port в main.go на другую и повторите попытку!

Остановка сервера

Чтобы закончить приколы, вы можете использовать ctrl-c в окне запуска сервера. Это освободит ресурсы (например, порт, который прослушивает сервер) и закроет программу.

Подведение итогов

Я надеюсь, что это было поучительно и немного весело. Я планирую создать серию статей, в которых я опишу настройку Docker (входит в репозиторий) и рассмотрю пару пакетов Go для создания простого пользовательского интерфейса. Как всегда, пожалуйста, оставьте мне отзыв о том, как я могу улучшить это!

Еще не все…

Я намерен продолжить эту серию и буду обновлять ссылки ниже. Будущие темы включают изучение фреймворков Go для создания внешнего интерфейса!

А пока вы можете продолжить, прочитав о том, как докеризировать приложение. Пожалуйста, оставьте отзыв о том, что еще вы хотели бы прочитать!