Ниже привел свою версию краткого изложения содержания данной книги.
Оглавление
Chapter 1 — Getting Started with Go
Chapter 2 — Go Fundamentals
Chapter 3 — User-Defined Types and Concurrency
Chapter 4 — Getting Started with Web Development
Chapter 5 — Working with Go Templates
Chapter 6 — HTTP Middleware
Chapter 7 — Authentication to Web Apps
Chapter 8 — Persistence with MongoDB
Chapter 9 — Building RESTful Services
Chapter 10 — Testing Go Applications
Chapter 11 — Building Go Web Applications on Google Cloud
Chapter 1 — Getting Started with Go
Устанавливаем Go, настраиваем GOROOT и GOPATH, создаем workspace для будущих проектов. Пишем «Hello, world» проект и тест для него. Утверждается, что Go очень подходит для Web-а и микросервисов.
Chapter 2 — Go Fundamentals
Понятие go-пакетов, их можно импортить по имени и прямо по url-у репозитория (тогда автоматически это будет latest версия, подробнее — см. ниже). Проект не соберется, если есть неиспользуемые импорты; при задании импорту алиаса "_" — это правило отменится. То же самое — для неиспользуемых переменных — хорошая идея для изгнания неиспользуемого кода из проекта.
Хорошая идея — циклы foreach, в которых внутри цикла автоматом доступны и индекс и само значение. То же самое при итерировании по map-у.
Отсутствие символа; в конце строк — они расставляются неявно автоматически, что приводит к необходимости явно указывать открывающую скобку { в той же строке, где условие / цикл / начало функции и т.п. Это приводит к меньшей вариативности правильно написаного кода, в итоге он удобно читается. Прямо с Go поставляется утилита gofmt, которая приводит форматирование к кошерному. Вообще — с Go в стандартной поставке идут только компилятор, форматтер и godoc, для генерации документации. Стандартная библиотека богата и избавляет от необходимости внедрения десятков сторонних пакетов в приложение.
Работа с коллекциями: массивы (fixed-length), слайсы (non-fixed length), карты. Слайсы имеют не только length, но и capacity — максимальную длину, до которой он может дорасти; при создании можно указать и то и другое.
То, что у Go вместо привычных всем exception-ов: Defer, Panic, and Recover
- defer в некотором смысле похоже на finally: при начале работы с каждым опасным местом, можем написать defer some_action, для закрытия сессии, соединения и т.п. Очередной такой defer будет добавлен в стек, и когда произойдет что-то плохое — они будут вызваны в обратном порядке
- panic в некотором смысле похоже на throw — паникуем, если что-то пошло не так. Т.к. исключений нету и функции возвращают что-то полезное (например сессию связи с БД) и ошибку, то паникуем, когда ошибка != nil
- recover используется внутри defer функции, для того чтобы при возможности восстановить нормальную работу приложения. Т.е. workflow такой: запаниковали, начали вызываться defer в обратном порядке (т.к. извлекаются из стека) и один из них (если смог) — вызвал recover, после чего работа приложения продолжится с той точки, где была вызвана паника
Chapter 3 — User-Defined Types and Concurrency
Система типов Go — строится на основе композиции с ключевым словом struct. При инициализации объекта неуказанные поля принимают значения по умолчанию для своего типа. Для добавления поведения экземплярам типов используются два подхода: pointer and nonpointer method receivers. В первом случае внутри метода он не может изменить содержимое экземпляра типа, во втором — может.
Нет необходимости явно указывать интерфейс и потом становиться заложником изначально спроектированной иерархии, используется утиная типизация: если два метода объявлены идентичным образом — они становятся имплементациями одного такого интерфейса автоматически.
Также можно перегрузить метод embedded типа — например соорудили структуру данных, но метод одного из полей должен вести себя по другому. Это поведение можно легко изменить, без необходимости объявления новых типов.
Concurrency в Go вкратце можно описать так — горутины общаются друг с другом посредством каналов, которые могут буферизированными и небуферизированными. На одном потоке ОС могут сидеть тысячи горутин. В случае небуферизированного канала (неинтересный случай) — имеет место синхронность выполнения двух горутин. Более интересен случай буферизированного канала, когда достигается настоящая асинхронность и параллелизм. Кол-во горутин на один поток ОС — настраиваемый параметр.
Chapter 4 — Getting Started with Web Development
Разбирают net/http библиотеку, состоящую из двух основных компонент:
- ServeMux (HTTP request router)
- Handler (их много, и это хэндлеры для HTTP реквестов)
Для начала приводится в пару строк пример создания сервера для отдачи статического контента.
Для описания хендлера функция должна иметь опеределенную сигнатуру. Это ограничение можно обойти, объявив handler в closure, которую вернет функция с любой нам удобной сигнатурой.
Тип http.Server позволяет гибко настроить сервер.
Gorilla web toolkit в отличие от net/http не входит в стандартную библиотеку, но является мощным request router, позволяющим законфигурить все под себя (реквесты можно матчить по хосту, пути, префиксу, заголовкам и параметрам запроса, HTTP-методам). Приводится пример разработки REST API при помощи Gorilla.
Chapter 5 — Working with Go Templates
Рассказывается о шаблонах, используемых для представления данных, — пакетах text/template и html/template. По шаблонам я не большой специалист — параллели не проведу — выглядят как параметризованные шаблоны, при желании можно запихивать немного логики в них, жить можно.
Chapter 6 — HTTP Middleware
Под термином HTTP Middleware подразумеваются штуки, помогающие в разработке Web API. Это в том числе:
- возможность выполнять определенные действия до и/или после срабатывания определенного HTTP-хендлера, а также объединять хендлеры в цепочки (почему-то напомнило сервлетные фильтры в Java)
- логгирование нужной информации в ходе обработки реквеста
- управление логикой обработки — передача потока обработки другому хендлеру при необходимости
Тут отметились такие third-party библиотеки, как Gorilla со своими хэндлерами и Alice с удобным способом объединения хендлеров в цепочки.
Также в качестве альтернативы Alice предлагается попробовать third-party пакет Negroni, решающий аналогичные задачи другим, неинтрузивным способом.
Chapter 7 — Authentication to Web Apps
Авторизация и аутентификация. Виды рассмотренных аутентификаций:
- Cookie-based. Плохая идея, надо сохранять сессию, сервис не stateless, плохо работает с кросс-доменными реквестами. Сразу отбросили
- Token-based. Хороший путь
- OAuth 2 с помощью таких провайдеров как Facebook, Twitter, GitHub и Google
- JSON Web Token (JWT)
Chapter 8 — Persistence with MongoDB
Рассматривается взаимодействие с MongoDB посредством mgo-драйвера, использование CRUD-операций, сортировка, индексы, менеджмент сессий.
Chapter 9 — Building RESTful Services
Объемная глава, где рассматривается полный цикл разработки REST-сервиса, с моделью, dao-слоем, роутами, JWT-аутентификацией, обработкой ошибок. Здесь убеждаешься, что действительно микросервисы на Go писать удобно.
Также здесь впервые за всю книгу затронули вопрос менеджмента зависимостей проекта при помощи Godep. Можно указать sha1 коммита в репо, откуда тянем зависимость, чтобы зафиксировать именно эту версию библиотеки, используемой приложением — ну все, у меня отлегло.
На закуску — разработанный сервис предлагается стартовать внутри Докер-контейнера, для чего также есть необходимый минимум кода.
Chapter 10 — Testing Go Applications
Показывают, как писать тесты. Нужные флажки могут добавить вербальности при их выполнении, измерить покрытие.
Отдельно стоит отметить Benchmark-тесты: позволяют проанализировать время выполнения определенных методов (запускает метод большое кол-во раз и вычисляет среднее время выполнения).
Тест-методы, начинающиеся с префикса Example, позволяют описать примеры использования тестируемого кода. При генерации документации — они будут включены в нее. Также можно указать, что ожидается в результате выполнения метода — тоже будет включено в документацию.
Есть возможность внутри тестов проверять, проводится ли тестирование с флажком -short, чтобы исключить запуск долгих тестов.
При написании теста — можно в нем прямо указать, что он может запускаться в параллели с другими, тогда при тестировании (запущенном с флажком -parallel) — параллельные тесты будут бежать параллельно.
Предлагается держать тесты в отдельном пакете от кода, который они тестируют. В этом случае правда измерение покрытия дает 0%.
Для тестирования веб-приложений используется пакет net/http/httptest.
Для BDD-тестирования предлагаются third-party пакеты Ginkgo и Gomega, где первый собственно BDD-фреймворк, а второй — матчер.
Chapter 11 — Building Go Web Applications on Google Cloud
Рассказывается о Google Cloud и как разместить там свое Go-приложение. Как оказалось — Google Cloud предоставляет не только
- Google Cloud SQL- MySQL-совместимое SQL решение и
- Google Cloud Datastore — NoSQL решение, но и
- Google Cloud Bigtable — NoSQL решение, «позволяющее хранить петабайты данных и идеально подходящее для Big Data задач»
Также Google предоставляет SDK, для создания Go-based эндпоинтов для бэкенда, и генерирует native клиентские библиотеки для iOS, Android, JavaScript и Dart, позволяя быстрее разрабатывать клиентские приложения. Также приводится пример приложения.
Автор: Андрей