[БЕЗ_ЗВУКА] В этом видео мы поговорим про конфигурирование вашего сервиса. Начнем со стандартного пакета flag. Пакет flag нужен для парсинга аргументов командной строки, там есть довольно много заготовленных типов. Например, вот в этой строчке я в commentsEnabled буду парсить булевую переменную, причем парситься будет не только true и false, но и t, f, маленькими, большими буквами, 0 и 1. Возвращает эта функция адрес на переменную. Там мы указываем имя, которое мы хотим использовать из аргументов командной строки, значение по умолчанию и комментарий на случай, если вдруг там встретится какая-то ошибка и нам выведется полный список того, что можно парсить. Int тоже со значением по умолчанию, там есть String и еще некоторые значения. Если же вы хотите парсить свой тип, то вы можете объявить его. Например, у меня есть тип AddrList, вот как он объявляется. Это всего лишь слайс стрингов, но я навесил на него две функции, для того чтобы он соответствовал интерфейсу. Первая функция String для дампа значений, вторая функция — Set, которая непосредственно устанавливает значения в эту переменную. Тут я разбиваю строку по запятой и ожидаю увидеть там адрес, то есть IP и порт. Если его нет либо он не валиден, я верну ошибку. И в конце я добавляю в общий список это. Таким образом, вы можете устанавливать собственные типы и парсить в том виде, в котором вам это нужно. Для того чтобы спарсить если стандартные типы можно сразу получить значения, то произвольный тип — вам нужно сначала объявить это значение в отдельную переменную, а потом вызвать функцию flag.Var. Это нужно для того, чтобы вы зарегистрировали парсинги для этой переменной, чтобы пакет знал, что нужно парсить в нее, потому что он не умеет возвращать нужный вам тип. В данном случае я объявляю переменную commentsServices и в init указываю, что спарсить нужно туда. init выполняется до функции main. Есть небольшой нюанс, который иногда, бывает, встречается у начинающих разработчиков, что в init пытается где-то подключение какой-то базы данных, причем аргументы, куда подключаться, передаются, парсятся через пакет flag. Дело в том, что до вот этой строчки — flag.Parse — у вас будут значения по умолчанию во всех переменных, которые вы указали во flag. И в произвольных типах, соответственно, будет то, что вы здесь объявили, в данном случае пустая переменная. Поэтому в init не пользуйтесь такими переменными, они реально спарсятся только после того, как вы вызвали flag.Parse. Также особо отмечу на наличие дефолтных значений. Иногда для небулевых переменных это очень, очень, очень удобно. Следующим подходом к парсингу конфига является указание одной большой структуры и, например, парсинг туда значений из json, или yaml, toml, ini, xml — откуда угодно. Этот подход имеет право на жизнь в том случае, если ваша программа умещается в один файл и нет никаких других пакетов, других файлов. Почему? Потому что если у вас есть другие пакеты, то сразу же ваш пакет начинает зависеть не только от самого себя, но и от какого-то внешнего пакета, и логика, получается, размазывается по нескольким пакетам. Там config, здесь логика, здесь нужно распарсить, не забыть, добавить — это неудобно, и так не надо делать. Однако если же, повторюсь, у вас всего один файл, то почему бы и нет. Единственный минус такого подхода — в том, что здесь нет никаких значений по умолчанию. Поэтому в случае, если с флагами я не указываю, вот здесь, я не указываю limit, параметр limit, он у меня возьмется по умолчанию, значение по умолчанию, то есть 10. В этом случае — вот мой json — параметра limit у меня нету, поэтому подставится то значение, которое является значением по умолчанию для данного типа. У меня это int, то есть туда подставится 0. Поэтому если хотите значение по умолчанию, в этом случае вам придется либо использовать какую-то другую библиотеку, которая может парсить [НЕРАЗБОРЧИВО], либо устанавливать их руками. И еще одним нюансом при конфигурировании ваших пакетов может быть желание при сборке указать какие-то значения, которые будут для вашего бинарника постоянными. Это не совсем конфигурирование приложения, однако это часто встречающийся нюанс, который стоит знать. В Go есть параметр ldflags, параметр к сборщику, и там можно указать значение переменной, которую вы хотите установить при компиляции. Там нужно указать пакет и, собственно, имя переменной. Имя переменной должно иметь тип String. Если вы хотите указать полный путь, соответственно, у вас будет что-то вроде github.com/ что-то такое. Такое тоже может быть. А, имя переменной. Вот как-то так. Давайте попробуем, это запустим. Да, флаги. Вот распарсились флаги мои, Comments per page 10, значение по умолчанию, services распарсились. Сейчас если я вдруг уберу порт, то мне выведется помощь, что ваш config неправильный. Вот почему: плохой адрес. Не распарсили, не указан порт. И, соответственно, все доступные опции: comments, limit и servers. Соответственно, это довольно удобно при конфигурировании. Теперь ldflags, теперь json, json. Вот обратите внимание: Comments per page 0, в то время как для флагов — это 10. 0 — потому что значение по умолчанию. Ну и теперь ldflags. Отлично. Еще раз покажу код. Version и Branch указаны пустые, тут нет никаких значений, однако при сборке я указывал ldfalgs main.Version, и значение из git прямо, и Branch — тоже значение из git. Таким образом, всегда когда мое приложение будет стартовать, я буду знать, из какого хеша оно было собрано. Таким образом, я могу всегда знать не только версию пакета, например, а и версия приложения, именно версия, которая лежит в системе контроля версия — она прямо зашита будет сразу в бинарник. Это очень удобно и хорошо. Далее мы рассмотрим, каким образом можно сделать онлайн-конфигурирование сервиса, используя Consul.