Открыть Электронные книги
Категории
Открыть Аудиокниги
Категории
Открыть Журналы
Категории
Открыть Документы
Категории
CO IN PRACTICE
11
MA NN I N G
S helter Is l a m d
Мэтт Батчер, Мэтт Фарина
GO НА ПРАКТИКЕ
Москва, 2017
УДК 004.438GO
ББК 32.973.26-018.1
Б28
УДК 004.438GO
ББК 32.973.26-018.1
Copyright © Manning Publications Со. 201 fi. First published in the English
language under the title ‘Go in Practice (9781633430075)’.
Все права защищены. Л ю бая часть этой книги нс может быть воспроиз
ведена в какой бы то ни было форме и какими бы то ни было средствами без
письменного разрешения владельцев авторских прав.
М атериал, изложенный в данной книге, многократно проверен. Но по
скольку вероятность технических ошибок все равно существует, издательство
не может гарантировать абсолютную точность и правильность приводимых
сведений. В связи с этим издательство не несет ответственности за возможные
ошибки, связанные г. использованием книги.
П редисловие ................................................................................................ 9
Введение................................................................................ 11
Благодарности......................................................................12
О книге.................................................................................. 15
Об авторах ....................................................................................................17
Об изображении на облож ке.............................................18
Г л а в а 2 . Н а д е ж н а я о с н о в а ................................................................51
2.1. CLI-приложения на G o .............................................................................52
2.1.1. Флаги командной строки..................................................................52
2.1.2. Фреймворки командной строки......................................................59
2.2. Обработка конфигурационной информации.......................................65
2.3. Работа с действующими веб-серверами................................................ 73
2.3.1. Запуск и завершение работы сервера............................................ 74
2.3.2. Маршрутизация веб-запросов......................................................... 79
2.4. Итоги............................................................................................................90
Г л а в а 3 . П а р а л л е л ь н ы е в ы ч и с л е н и я в G o ............................92
3.1. Модель параллельных вычислений в Go.............................................. 92
3.2. Работа с сопрограммами...........................................................................93
3.3. Работа с каналами....................................................................................108
3.4. Итоги..........................................................................................................122
Г л а в а 5 . О т л а д к а и т е с т и р о в а н и е ............................................. 155
5.1. Определение мест возникновения ошибок.........................................156
5.1.1. Подождите, где мой отладчик?..................................................... 156
5.2. Журналирование.......................................................................................157
5.2.1. Журналирование в G o..................................................................... 157
5.2.2. Работа с системными регистраторами.........................................168
5.3. Доступ к трассировке стека................................................................... 173
5.4. Тестирование............................................................................................. 176
5.4.1. Модульное тестирование................................................................177
5.4.2. Порождающее тестирование.......................................................... 183
5.5. Тестирование производительности и хронометраж.......................... 186
5.6. Итоги..........................................................................................................194
Содержание 7
Ч а с т ь III. И н т е р ф е й с ы п р и л о ж е н и й ........................................195
Г л а в а 6 . П р и е м ы р а б о т ы с ш а б л о н а м и H TM L
и э л е к т р о н н о й п о ч т ы ..........................................................................196
6.1. Работа с HTM L-шаблонами.................................................................. 197
6.1.1. Обзор пакетов для работы с HTM L-разметкой
в стандартной библиотеке........................................................................197
6.1.2. Добавление функциональных возможностей в шаблоны...... 199
6.1.3. Сокращение затрат на синтаксический разбор шаблонов...... 203
6.1.5. Соединение шаблонов.....................................................................207
6.2. Использование шаблонов при работе с электронной почтой........ 218
6.3. Итоги..........................................................................................................220
Г л а в а 8 . Р а б о т а с в е б - с л у ж б а м и ...............................................255
8.1. Использование R EST APT......................................................................256
8.1.1. Использование HTTP-клиента..................................................... 256
8.1.2. При возникновении сбоев.............................................................. 258
8.2. Передача и обработка ошибок по протоколу H T TP.........................263
8.2.1. Генерация пользовательских ошибок.......................................... 264
8.2.2. Чтение и использование пользовательских сообщений
об ошибках.................................................................................................. 267
8.3. Разбор и отображение данных в формате JS O N ............................... 270
8.4. Версионирование R EST API................................................................. 274
8.5. Итоги..........................................................................................................279
Когда я услышал, что Мотт Фарина и Мотт Батчер начали работу над
новой книгой о языке Go, это меня очень взволновало. Они оба много
лет были важнейшими действующими лицами в экосистеме Go, об
ладают большим опытом работы и способны добавить в аромат со
держания этой книги запахи специй прошлых учебных пособий. Эта
книга должна стать преемницей книги «Go in Action», развивающей
заложенные там основы и переводящей их в практическое русло.
Книга разбита на четыре простые в освоении части, каждая из ко
торых имеет собственную направленность. Часть 1 освежает в памяти
основные идеи языка Go. Если вы спешите и уже обладаете навыка
ми, позволяющими уверенно писать код на языке Go, можете смело
пропустить этот раздел, хотя я не рекомендую этого делать. Знако
мясь с окончательным вариантом рукописи, я обнаружил в ней само
родки такого размера, что, полагаю, главы этой части будут полезны
всем читателям.
Часть 2 погружает читателя в недра механики управления Go-
приложениями. Глава об ошибках является одним из лучших описа
ний Go-ошибок из всех, прочитанных мной прежде, а глава, посвящен
ная отладке pi тестированию, содержит массу полезной информации
об этом важном этапе разработки, помогающем поднять приложение
с уровня, требующего доказательства идеи, до уровня надежной про
изводственной системы.
В третьей части вы узнаете о способах создания пользовательских
интерфейсов. Глава но шаблонам является отличным руководством
по самой сложной, как многие полагают, части экосистемы Go. Она
знакомит с практическими приемами многократного использования
шаблонов и создания выразительных веб-интерфейсов. Приведен
ные примеры соответствуют уровню книги, поскольку трудно найти
примеры использования шаблонов, легко переносимые в реальные
приложения. Затем вы увидите, как создавать и использовать REST
API, и познакомитесь с хитростями управления версиями этого API.
Заключительная часть книги посвящена теме функциональной
совместимости, необходимой практически любому современному
приложению. Она позволяет глубоко погрузиться в облачную инф
раструктуру и увидеть, как язык Go вписывается в модель облачных
10 Предисловие
К а к организована книга
Одиннадцать глав разделены на четыре части.
Часть I «Основные понятия и принципы» закладывает фундамент
для будущих приложений. Глава 1 описывает основы языка Go и бу
дет полезна всем, кто еще нс знаком с ним или хотел бы узнать о нем
больше. В главе 2 рассказывается о создании консольных приложе
ний и серверов, а в главе 3 - об организации параллельных вычисле
ний в Go.
Часть II «Падежные приложения» включает главы 4 и 5, охваты
вающие темы ошибок, аварий, отладки и тестирования. Цель этого
раздела рассказать о создании надежных приложений, способных
автоматически справляться с возникающими проблемами.
Часть III «Интерфейсы приложений» содержит три главы и охва
тывает диапазон тем, от генерации разметки H TM L и обслуживания
ресурсов до реализации различных API и работы с ними. Многие
Go-приложения поддерживают взаимодействие через веб-интерфейс
и R EST API. Эти главы охватывают приемы, помогающие в их кон
струировании.
Часть IV «Облачные приложения» содержит остальные главы, по
священные облачным вычислениям и генерации кода. Язык Go разра
батывался с учетом нужд облачных технологий. В этой части демон
стрируются приемы, позволяющие работать с облачными службами
и приложениями и даже с микрослужбами в них. Кроме того, она
охватывает приемы генерации кода и метапрограммирование.
В книге описывается 70 приемов, и в каждом случае сначала ста
вится задача, затем дается решение и в заключение обсуждаются при
чины выбора тех или иных подходов.
16 О книге
Авторский интернет-форум
Приобретая книгу «G o на практике», вы получаете свободный доступ
к закрытому веб-форуму издательства Manning Publications, где м ож
но оставить отзыв о книге, задать технические вопросы и получить
помощь авторов или других пользователей. Чтобы получить доступ
к форуму и зарегистрироваться на нем, перейдите на страницу www.
m anning.com /books/go-in-practice. Здесь вы найдете информацию
о том, как пользоваться форумом после регистрации, какого рода по
мощь можно получить и правила поведения на форуме.
Издательство Manning, идя навстречу пожеланиям своих читате
лей, предоставляет площадку для конструктивного диалога между
читателями, а также между читателями и авторами. Это не обязывает
авторов к участию в нем —любое их участие является добровольным
(и никак не оплачивается). Задавайте авторам сложные вопросы, что
бы заинтересовать их!
Авторский интернет-форум и архивы предыдущих дискуссий будут
доступны на веб-сайте издателя, пока книга продолжает печататься.
Об авторах
ОСНОВНЫЕ ПОНЯТИЯ
И ПРИНЦИПЫ
Введение в язык Go
inport (
"fmt"
func Nair.es() (strin g, string) <r О Определена как возвращающая две строки
return "Foo", "Bar" <- О Возвращаются две строки
func main() {
nl, n2 := Names () © Значения присваиваются двум переменным
fmt. Frintln (til, п2) и выводятся
func main() {
nl, n2 := Names () < - О Значения присваиваются двум переменным
fmt.Printlnlnl, п2)
: nport. (
"buiic"
":m t"
"net"
func main() {
conn, _ := net. Dial ("tcp", "gclar.g.org:80") <- О Соединение no TCP
fmt.Fprintf(conn, "GET / HTTP/1. C\r\n\r\n") < - © Отправка строки через
statu s, _ := соединение
**bufio .NewReader (ccr.r.) .Readstring (' \n ') © Вывод первой строки ответа
fmt. Frin tln (statu s)
import (
"tint"
"io /io u til"
"net/http"
func mainO {
resp, _ :=
‘• http.Get ("http:.//example.c o n /") <- Создание HTTP-запроса GET
body, _ :=
‘•ioutil.ReadAll(resp.Body) <- Чтение тела ответа
fm t.Frintln(string(body) ) Вывод тела в виде строки
resp.Body.Close () <- Закрытие соединения
H TM L
Работая над созданием веб-сервера, невозможно обойти стороной
разметку HTML. Пакеты html и html/template отлично справляются
с формированием веб-страниц. Пакет html имеет дело с экраниро
ванной и неэкранированной HTM L-разметкой, а пакет htir.l/template
предназначен для создания многократно используемых HTML-
шаблонов. Модель безопасности обработки данных прекрасно доку
ментирована, и имеется ряд вспомогательных функций для работы
с HTML, JavaScript, и многим другим. Система шаблонов поддержи
вает возможность расширения, что делает ее идеальной основой для
реализации более сложных действий.
28 Введение в язык Go
Криптография
В настоящее время криптография стала обычным компонентом
приложений, используемым для работы с хэшами или шифрования
конфиденциальной информации. Язык Go предоставляет часто ис
пользуемые функциональные возможности, включающие поддержку
MD5, нескольких версий Secure Hash Algorithm (SH A), Transport Layer
Security (TLS), Data Encryption Standard (DES), Triple Data Encryp
tion Algorithm (TDEA), Advanced Encryption Standard (AES, прежний
Rijndael), Keyed-Hash Message Authentication Code (HMAC) и многих
других. Кроме того, в нем имеется криптографически безопасный ге
нератор случайных чисел.
Кодирование данных
При совместном использовании данных несколькими системами
встают типичные для современных сетей задачи кодирования, такие
как: обработка данных в формате baseG4, преобразование данных
в формате JS O N (JavaScript Object Notation) или X M L (Extensible
Markup Language) в локальные объекты.
Язык Go разрабатывался с учетом необходимости решать задачи
кодирования. Внутренне Go использует только кодировку UTF-8. Это
неудивительно, поскольку создатели Go прежде занимались создани
ем UTF-8. Но далеко не всегда при обмене между системами исполь
зуется кодировка UTF-8, поэтому приходится иметь дело с самыми
разными форматами данных. Для их обработки в языке Go имеются
соответствующие пакеты и интерфейсы. Пакеты поддерживают та
кие возможности, как преобразование строк JSON в экземпляры объ
ектов, а интерфейсы обеспечивают переключение между кодировка
ми и добавление новых способов работы с кодировками посредством
подключения внешних пакетов.
Сопрограммы - функции,
выполняющиеся
до-подпрограмма ^ конкуренте, - рабшакл
в потоках, управляемых
до-подпрограмма планировщиком Go
Планировщик Go способен
^ до-подпрограмма ^ перемещать сопрограммы
между потоками операци
... онной системы. Если поток
заблокирован, скажем
до-подпрограмма ^ операцией ввода-вывода,
другие сопрограммы могут
Поток перемещаться в другие
потоки
Обрабатывающее ядро
H e llo W o r ld 2
3
4
30 Введение в язык Go
func main() {
qo count () <- 0 Вызов до-подпрограммы
time.Sleep(time.Millisecond * 2)
fmt.Frintln("Hello World")
time.Sleep(time.Mi Hi second * 5)
func printCcur.t (c chan int) [ <- О Канал для передачи целого значения
пшп := О
for num >= 0 {
num = <-с <- © Ожидание целого значения
fmt.Print(num, " ")
func main() {
c := make(chan int) 4 - © Создание канала
a := lJin t{8, 6, 7, ь, 3, 0, 9, -1}
go printCount(c) < - © Вызов сопрограммы
for , v := range a <- © Запись целого значения в канал
Управление пакетами
Диспетчеры пакетов существуют для многих современных языков
программирования, но у скольких из них функция управления паке
тами является встроенной? В языке Go она встроенная, и тому есть
две веские причины. Самая очевидная - продуктивность программис
та. Вторая причина - ускорение компиляции. Управление пакетами
разрабатывалось с учетом нужд компилятора. Это один из аспектов,
определяющих быстроту компиляции.
Идею пакетов в Go проще всего изучать па примере стандартной
библиотеки (ее демонстрирует следующий листинг), которая органи
зована на основе системы управления пакетами.
func main() {
fmt. F r i n t l n ("Hello World!") <- Использование функции пакета fmt
Тестирование
Тестирование - общепринятый элемент разработки программ
ного обеспечения, и по мнению некоторых - весьма существенный.
В Go имеется полноценная система тестирования, включающая пакет
в стандартной библиотеке, средс тво выполнения тестов из командной
строки, средство оценки охвата кода тестами и средство обнаружения
состояний «гонки за ресурсами».
Процесс создания и выполнения тестов достаточно прост, как по
казано в следующем листинге.
im port "fmt"
func qetNarr.eO s t r i n g {
r e t u r n "World!"
func main() {
name := cetNsmei)
f m t . F r i n t i n ( " H e l l o ", name}
Примечательные особенности языка Go ❖ 35
Охват кода
Помимо выполнения тестов, система тестирования поддерживает
создание отчетов с полной детализацией охвата кода тестами, вплоть
до уровня инструкций, как показано на рис. 1.14.
ПРИМЕЧАНИЕ В версии Go 1.5 команды получения оценки охвата
тестам и стали частью ядра Go. Д о версии 1.5 команда cover о тно
силась к дополнительны м инструментам.
package main
im p o rt “ fm t"
fu n c getName() s t r in g {
r e tu r n “ W o rld !"
>
fu n c m a in () {
name := getNamef)
f m t . P r in t ln ( " H e l lo ” , name)
>
Форматирование
Как предпочтительнее оформлять отступы в исходном коде, сим
волами табуляции или пробелами? Вопросы форматирования и сти
ля затрагиваются и обсуждаются всякий раз, когда речь заходит о со
глашениях оформления кода. Сколько можно было бы сэкономить
времени, отказавшись от этих дебатов? Пользователям языка Go нет
смысла тратить время на обсуждение форматирования или других
языковых идиом.
На странице http://golang.org/doc/effective_go.htnnl можно озна
комиться с руководством «Effective Go» , посвященным идиомати
ческим особенностям языка Go. В нем описаны стили и соглашения,
используемые всеми членами G o-сообщества. Эти соглашения облег
чают чтение и изменение написанных на языке Go программ.
Среда Go включает встроенный инструмент форматирования, под
держивающий большинство рекомендаций по оформлению. Доста-
1
Краткий пересказ па русском можно найти по адресу: http://golang-club.
blogspot.ru/2016/03/effective-go. html. - Прим. ред.
38 Введение в язык Go
1.3.1. С и Go
Язык Go с самого начала рассматривался как альтернатива языку С
для разработки приложений. Поскольку источником вдохновения
Мес I о языка Go среди дру| их языков i ipor раммирования ❖ 39
С + Go = ego
Язык Go поддерживает использование библиотек, написанных на С,
в программах на Go. В состав Go входит библиотека инструментов
поддержки совместимости с языком С. Эта библиотека облегчает, на
пример, переход от строк в стиле С к строкам языка Go. Кроме того,
инструменты Go позволяют компоновать программы из исходного кода
на языках С и Go. Язык Go также поддерживает обертки Simplified Wrap
per and Interface Generator (SWIG). Получить общее представление об
имеющихся возможностях можно с помощью команд со help с и go doc ego.
1.3.2. Java и Go
Jav a долгое время является одним из самых популярных языков про
граммирования и используется для разработки широкого спектра
проектов, от серверных до мобильных Android-приложений и кросс -
платформсниых приложений для настольных компьютеров. Go из
начально разрабатывался как системный язык. С течением време
ни стало возможным использовать его для разработки мобильных
и всб-ириложсиий, тем не менее Go нс позволяет с легкостью писать
настольные приложения. Его превосходные качества проявляются
только при использовании по назначению.
Учитывая популярность Jav a и возможность его применения для
создания широкого спектра приложений, почему у кого-то может воз
никнуть желание пользоваться языком Go? Языки Java и Go имеют
схожий синтаксис, но в действительности они сильно отличаются.
Программы на Go компилируются в единственный двоичный файл,
предназначенный для определенной операционной системы. Он со
держит среду выполнения Go, все импортированные пакеты и само
приложение, то есть все, что необходимо для выполнения програм
мы. В Jav a используется другой подход. Приложения на Java требуют
установки среды выполнения в операционной системе. Они упако
вываются в файл, который может выполняться в любой системе с со
ответствующей средой выполнения. Приложения требуют наличия
совместимой версии среды выполнения.
Это различие подходов, проиллюстрированное на рис. 1.5, опре
деляет способ использования приложений. Для развертывания Go-
Место языка Go среди дру| их языков 11рограммирования ❖ 41
Процесс
Запрос к приложению на Python
или РНР поступает на веб-сервер. Веб Процесс
Затем веб-сервер передает его сервер
одному из процессов
Процесс
Операционная система
Работа с пакетами
Экосистема Node.js включает сообщество и инструментальные
средства для обработки и распространения пакетов. Они могут варьи
роваться от библиотек до утилит командной строки и полноценных
приложений. В комплект Node.js обычно входит диспетчер пакетов
npm. Центральный репозиторий с информацией о доступных пакетах
находится па сайте w w w .n p m js.o rg . Когда поступает команда загру
зить пакет, диспетчер извлекает метаданные о нем из центрального
репозитория и загружает пакет из исходного месторасположения.
Как упоминалось ранее, язык Go имеет собственную систему рабо
ты с пакетами. В отличие от Node.js, где метаданные и дополнитель
ная информация располагаются в центральном репозитории, язык Go
не имеет центрального хранилища, и пакеты загружаются из исход
ного местоположения.
П0Д1 ОI GBKd И ddl lyLK I ipOl pdM M bl Hd ЯЗЫКе Go 45
1.4.1. Установка Go
Установка Go - довольно простая процедура. Вся необходимая ин
формация о получении и установке Go приводится на странице
http://golang.org/doc/install. Здесь перечисляются поддерживаемые
операционные системы, аппаратное обеспечение и многое другое.
Для Microsoft Windows и Mac O S X имеются инсталляторы, кото
рые позаботятся об установке. Этот процесс настолько же прост, как
установка любой другой программы. Пользователи Homebrew на OS
X могут установить Go командой brew i n s t a l l go.
Установка Go в Linux предусматривает более широкий диапазон
вариантов. Установить Go можно с помощью встроенного диспет
чера пакетов, такого как a p t-g e t или yum. Но, как правило, они уста
навливают не самую последнюю версию, притом, что новые версии
работают быстрее и поддерживают новые функциональные возмож
ности. Следуя инструкциям по установке Go, молено загрузить са
мую последнюю версию языка, разместить ее в системе и добавить
пути к исполняемым файлам в переменную окружения PATH. В вер
сиях Linux, поддерлсивающих систему управления пакетами Debian,
таких как Ubuntu, установить последнюю версию Go можно с по
мощью godeb. Пояснения автора godeb о процедуре установки мож
но найти на странице http://blog.labix.org/2013/06/15/in-flight-deb-
pack ag es-o f-g o .
4Б Введение в язык Go
1.Б. И тоги
Язык Go предназначен для работы на современном аппаратном обе
спечении и разработки современных приложений. Он использует
последние технологические достижения и инструменты, упрощаю
щие процесс разработки. В этой главе мы рассмотрели основные до
стоинства языка программирования Go и познакомились:
О с философией языка Go, заключающейся в простоте и расши
ряемости, позволившей создать удобный язык и окружающую
его экосистему;
О с особенностями языка Со, помогающими использовать пре
имущества современного оборудования, такими как сопро
граммы, обеспечивающие параллельное выполнение;
О с сопровождающим язык Go набором инструментов, включаю
щих средства тестирования, управления пакетами, форматиро
вания и документирования;
О с характеристиками Go в сравнении с такими языками, как С,
Java, JavaScript, Python, РН Р и другими, а также узнали, для
каких задач он подходит лучше всего;
О с порядком установки и использования Go.
50 Введение в язык Go
Надежная основа
Оконные приложения
Go, как системный язык, не имеет встроенной поддержки для созда
ния оконных приложений, подобных тем, что используются в Microsoft
Windows или Mac OS X. В Go-сообществе велись эксперименты по их
разработке, но они не имели четкой направленности.
Листинг 2.2 ♦> Исходный код приложения Hello World, использующ его
пакет flag: flag_cli.go
package ir.ain
inport (
"flag" <- Импорт стандартного пакета flag
О Создание новой
I переменной из флага
func i n i t () {
flag.EoclVar(Sspanish, "spanish", fa ls e , "Use Spanish language.")
flag.BoolVar (Sspanish, " s " , "a lse , "Use Spanish language.")
GO-FLAGS
Па к е т
Некоторые пакеты обработки флагов, разработанные r сообщест
ве, нарушают соглашения, принятые в пакете flag из стандартной
библиотеки. Одним из таких пакетов является пакет github.com/
jessevdk/go-flags. Он поддерживает обработку флагов в стиле Linux
и BSD, обеспечивая еще больше возможностей, чем в пакете gnuflag, но
использует совершенно другой интерфейс и стиль. Он поддерживает
следующие возможности:
О короткие флаги, такие как -f, и группы коротких флагов, такие
как -fg;
О многосимвольные, или длинные, флаги, такие как - -flag;
О группы флагов;
О автоматическое создание справочного описания в удобной
форме;
О поддержка значений флагов в нескольких форматах, например:
-p/usr/local, -р /u sr/local и -p=/usr/'lccal;
О один и тот же параметр может извлекаться многократно и раз
биваться на фрагменты.
58 Надежная основа
"fmt"
flags "github. com/;essevdk/go-flags" <- Импорт пакета go-flags Сприсвоением
) псевдонима flags
v a r o p ts s t r u c t { О Структура
Name s t r i n g ' s h o r t : " n " lo n g :" n a m e " d e f a u l t : " W o r l d " с определениями
'• ■ d e s c r i p t i o n : " A name t o s a y he__o t c . " ' флагов
Spanish bool 's h o rt:" s " long:"spar.ish"
'•description:"Use Spanish Language"'
func main() {
fla g s .F a r s e ( s o o t s ) <- © Извлечение значений флагов в структуру
Обсуж дение
Сочетающий в себе поддержку маршрутизации, парсинг флагов,
извлечение параметров и возможность подготовки справочной доку
ментации, фреймворк c li .до обеспечивает простейший способ разра
ботки консольных приложений.
Простое консольное приложение
Перед знакомством с консольным приложением, поддерживаю
щим несколько команд, имеет смысл остановится на консольном при
ложении, осуществляющем одно действие. Вы сможете использовать
его как фундамент для расширения возможностей и поддержки не
скольких команд и подкоманд. На рис. 2.1 изображена структура при
ложения командной строки с одним действием.
GT.ORAT, OPTIONS:
—name, -n 'World' Who to say h ello to.
—help, -h show help
—version, -v p rin t "he version
import (
"fmt"
"os"
func main() {
app := cli.NewAppi) О Создание нового экземпляра приложения
app.Name = "h e llo _ c li"
app.Usage = "Print h ello world"
app.Flags = []c li.F la g { © Настройка флагов
c li .Strin gFlag{
Marne: "name, n",
Value: "World",
Usage: "Who to say hello to.
h
Ко м ан ды и подком анды
----- 1-----
Подкоманда - команда,
вложенная в другую команду
import (
" fir.t"
"os"
" q cp k q .in /u rfav e/cli.v l"
func main() {
app : = c l i .NewApp')
app.Usage = "Count up or down."
app.Commands = [] c.1 i .Command} <- О Определение одной или нескольких команд
},
}
app.Run(os.Argo)
https://12factor.net/ru/. - Прим.ред.
OOpdOotKd конфи! ypdLil/IG H H O I/l HHtJjOpMdUHH ❖ 67
О бсуж дени е
Р ассм о тр и м J S O N -ф ай л config. j son со сл едую щ и м содерж и м ы м :
"enabled": true,
"path": "/u sr/lo cal"
func mainO {
file, _ := os. Open ("co nf . j son") «- © Открытие конфигурационного файла
defer file.C lose()
decoder := j son. NewDecoder (file) © Извлечение JSO N-значений в переменные
conf := configuration{}
err := decoder.Decode(iconf)
i f e^r != nil {
fm t.Println("Error:", err)
Реш ение
import (
"fmt"
"github.com/kylelemons/go-gypsy/yaml" «- О Импорт пакета YAM L сторонних
) производителей
func main() {
config, err := yaml.ReadFile ("cor.f .yaml") <- © Чтение и анализ YAM L-файла
i f err != n il {
fm t.Println(err)
; Сорока комментария
; Section]
enabled = true
path = /usr/local if еще один кошентарий
Ф р агм ен т н следующ ем листинге извлекает и выводит данные из
этого файла.
import (
"fltlt."
"gopkg. i г/gcfg. v1" +- О Импорт пакета для работы с INI-файлами
tunc main() {
config := struct ( © Создание структуры для хранения
Section struct { конфигурационных значений
Enabled bool
Path string
func main() {
h ttp. Handl е Func (" /", homePage)
http.ListenAndServe ( " : "+os.Getenv("PORT"), ni_) <- О Извлечение значения
переменной PORT
из окружения
func hoir.eFaqe(res http.ResponseWriter, req * http.Request) {
i f req.URL.Path != " /" {
http.NotFound(res, req)
return
:nport (
"fmt."
"net/http"
"os"
)
func mainO {
http.HandleFuns ("/shutdown", shutdown) Регистрация специального пути
http.HandleFunsi"/", homePaqe) для завершения работы сервера
http.ListeriAndServe(":8080", nil)
Обсуж дение
В Braintree, подразделении компании PayPal, создан пакет manners,
позволяющий корректно завершить работу с использованием того же
интерфейса, что предоставляет функция L iste n A n d S e rv e из стандарт-
нош пакета h ttp . Внутренне пакет использует сервер из стандартного
пакета h t t p и контролирует соединения с помощью функции /Jai tGroup
из пакета sync. Метод W aitG rcup предназначен для управления сопро
граммами. Следующий листинг демонстрирует реализацию простого
сервера, использующего пакет manners.
Л и с ти н г 2.15 ❖ Штатное завершение работы с помощью пакета
manners: nanners_shu:down. go
package main
inport (
"fmt"
"net/http"
"os"
"os/sign al"
"github.com/braintree/nanners"
func mainO {
handler := newHandler() <- О Получение экземпляра обработчика
http://example.com/foo#bar?baz=quo
Р е ш е н и е : н еско лько о б ра бо тч и к о в
Данное решение расширяет прием из листинга 1.16 и использует
функции-обработчики для каждого из путей. Оно было представле
но в руководстве «Writing Web Applications» ( h ttp ://g o lan g .o rg /d o c /
articles/w iki/) и реализует шаблон, подходящий для веб-приложений
с несколькими простыми путями. Такой подход имеет определенные
ограничения (о них вы узнаете чуть ниже), которые могут вынудить
вас использовать другой прием, описываемый вслед за этим.
О бсуж д ени е
Начнем с простой программы, представленной в следующем
листинге и демонстрирующей использование нескольких обработ
чиков.
Л истинг 2.16 •> Несколько функций-обработчиков: m u ltip lejiand lers.go
package ir.ain
inport (
"fm t"
"net /http"
"strings"
func main() {
http.HandleFunc("/hello", hello) О Регистрация обработчиков
http.Handlet'unc("/goodbye/", goodbye) URL-адресов
h ttp .HandleFunc("/ ", homePage)
http.ListenAndServeC':8080", nil) ч- Запуск веб-сервера,
подключенного кпорту 8080
func hello(res http.ResponseWriter, rec * http.Request) ( ч- © Функция-
query := req.'JRL.Query () © Получение имени обработчик
паше := query.Get ("папе") ИЗстроки запроса для пути/hello
i f паше == "" {
name = "Inigo Montoya"
import (
"fnt"
"net/http"
"path" <- Импорт пакета path для обработки URL-путей
"strings"
)
func mainO {
pr := newPathResolver () -с- О Получение экземпляра маршрутизатора
pr.Add ("get /hello", hello) I © Отображение путей в функции
pr.Add("* /goodbye/*", goodbye) I
http.ListenAndServe(":8080", pr) < - © Передача маршрутизатора HTTP-серверу
inport (
"fmt"
"net/http"
"regexp" ч- Импорт пакета для работы с регулярными выражениями
"strings"
)
func main() {
r r := newPathResolver()
rr.Add("GET /hello", hello) I О Регистрация
rr.Add("(GET|HEAD) /goodbye(/?[A-Za-z3-9]*)?", goodbye) | путей ифункций
http.ListenAndServe(":8080", rr)
2.4. И тоги
После реализации фундаментальных элементов можно переходить
к более специфичной части приложения, которая, по сути, и делает
его полезным. В этой главе мы познакомились с несколькими базо
выми элементами:
О удобная обработка параметров командной строки. Здесь был
охвачен диапазон от легковесных решений до простых фрейм
ворков для создания консольных приложений и утилит;
О различные способы извлечения конфигурационной информа
ции в разных форматах из файлов и переменных окружения;
Итоги 91