
персидское слово, которое означает «маленький» или «li'l». Он часто используется для обозначения девушки при флирте (со значением, Li'l Girl)
Городской словарь
Добро пожаловать в Koochooloo : элегантный, практический проект, созданный для оптимизации разработки приложений Golang. Имея хорошо организованную архитектуру, Koochooloo интегрирует жизненно важные функции, такие как обработка базы данных и управление конфигурацией, иллюстрируя лучшие практики в создании надежных приложений для отдыха с GO.
init : избегать глобальных и сложности функций init , чтобы сделать вещи простыми. Используя fx в качестве нашей структуры впрыска зависимостей, Koochooloo поставляет:
fx в тестировании с той же легкостью, что и в производстве.Отправляйтесь в путешествие с Koochooloo и переопределите свой подход к созданию Restful Applications в Go. Независимо от того, расширяете ли вы свой набор навыков или создаете прочную основу для сложных приложений, Koochooloo является вашим партнером в области эффективного, чистого и масштабируемого дизайна программного обеспечения.
Прежде всего, пакет cmd содержит двоичные файлы этого проекта с использованием COBRA. Приятно иметь простые двоичные файлы для таких задач, как миграции базы данных, которые можно запустить на этапе инициации проекта. Каждый двоичный файл имеет свой main.go в своем пакете и регистрируется с функцией Register . В root.go cmd эти функции Register из подкомандов вызываются. Вот пример для функции регистрации:
// Register server command.
func Register ( root * cobra. Command ) {
root . AddCommand (
& cobra. Command {
Use : "server" ,
Short : "Run server to serve the requests" ,
Run : func ( _ * cobra. Command , _ [] string ) {
fx . New (
fx . Provide ( config . Provide ),
fx . Invoke ( main ),
). Run ()
},
},
)
} Снова каждая команда регистрирует свой флаг сам по себе, поэтому мы отделяем от других команд. Иногда нам нужно иметь общие флаги между командами, тогда лучше иметь их в конфигурации. Для более позднего случая koanf может помочь нам со структурой, как показано ниже:
func Register ( fs * pflag. FlagSet ) {
fs . StringP (
"url" , "u" ,
nats . DefaultURL ,
fmt . Sprintf ( "nats server url(s) e.g. %s" , nats . DefaultURL ),
)
}Эта функция зарегистрирует общие флаги, а затем мы загружаем конфигурацию на основе их со следующей функцией:
k := koanf . New ( "." )
if err := k . Load ( posflag . Provider ( fs , "." , k ), nil ); err != nil {
log . Errorf ( "error loading config.yml: %s" , err )
}
if err := k . Unmarshal ( "" , & instance ); err != nil {
log . Fatalf ( "error unmarshalling config: %s" , err )
}Основной частью каждого приложения является его конфигурация. Есть много способов иметь конфигурацию в проекте от файла конфигурации до переменных среды. У Коанфа есть все в одной красивой упаковке. Основные моменты здесь:
config модуле, и он будет передаваться ему в своем инициации.PS Koanf намного лучше, чем Viper для напечатанной конфигурации. Под типичной конфигурацией я имею в виду, что у вас есть определенная структура для конфигурации, а затем загружать конфигурацию из многих источников в нее.
Для установки KOANF вы можете использовать следующие команды:
go get -u github.com/knadh/koanf/v2
go get -u github.com/knadh/koanf/providers/file
go get -u github.com/knadh/koanf/providers/env
go get -u github.com/knadh/koanf/providers/structs
go get -u github.com/knadh/koanf/parsers/toml Пакеты и услуги, которые определены в пакете domain , используют только другие пакеты из domain без использования каких -либо сторонних пакетов. Эти пакеты и услуги определяют основные концепции домена.
Существует пакет db , который отвечает за подключение к базе данных. В этом пакете используется конфигурация базы данных, которая определена в модуле config и создает экземпляр базы данных. Это хорошая идея для того, чтобы пить вашу базу данных, чтобы иметь полностью уверенный в экземпляре базы данных, прежде чем продвигаться вперед. Также для того, чтобы иметь представление о здоровье базы данных, вы можете периодически вызывать эту функцию Ping и сообщать о ее результате с помощью метрик (чего я здесь не делал).
Модели проектов определены в model . Эти модели используются внутренне, но могут использоваться в response или пакете request . В этом пакете нет структуры для общения с базой данных.
Репозитории отвечают за то, что мы поднимались с базой данных для хранения или извлечения моделей. Репозитории - это interface , и для них есть бетон и издевательная реализация. Бетонная реализация используется в основном коде, а издевательная сделка используется для тестов. Обратите внимание, что тесты на репозитории являются обидчивыми и выполняются с фактической базой данных.
HTTP Handler определяется в пакете handler . Echo - это потрясающая http -структура, в которой вам нужно. Каждый обработчик имеет свою структуру с методом Register , который регистрирует свой маршрут в данную группу маршрутов. Route Group - это концепция Echo Framework для группировки маршрутов по конкретному родительскому пути. У каждого обработчика есть то, что ему нужно в своей структуре. Структура обработчика создается в main.go , затем зарегистрируйтесь в их группе.
type Healthz struct {}
// Handle shows server is up and running.
func ( h Healthz ) Handle ( c echo. Context ) error {
return c . NoContent ( http . StatusNoContent )
}
// Register registers the routes of healthz handler on given echo group.
func ( h Healthz ) Register ( g * echo. Group ) {
g . GET ( "/healthz" , h . Handle )
} Все метрики собираются с использованием Prometheus на основе открытой температуры. Каждый пакет имеет свой metric.go , который определяет структуру, содержит метрики и имеет методы их изменения. Для перехода из Прометея в другой сервис вам просто нужно изменить telemetry . Метрики не являются глобальными, и они созданы для каждого экземпляра отдельно благодаря открытой телеметрии. Для лучшего контроллера в конечной точке метрик есть еще один HTTP -сервер, который определяется в пакете telemetry для мониторинга.
Хорошо иметь разделенные пакеты для запросов и ответов. Эти пакеты также содержат логику проверки. Одним из хороших валидаций в Go является Ozz-Validator. После предоставления метода проверки, после получения запроса вы можете проверить его с помощью его метода с легкостью.
Регистрация одной из важнейшей части применения. В начале нет необходимости иметь что -то большее, чем простые журналы Stdout. Но в будущем вам необходимо пройти в систему, и отправите их в систему агрегации, потому что, когда ваша система выращивает проблемы с проблемами текста в журналах текста.
ZAP - один из лучших журналистов для регистрации структуры. zap заставляет вас передать его в свой детский модуль, и вы также называете регистраторов с Named методом. Используя именованный журнал Logger, вы можете легко найти журналы модуля в вашем агрегаторе журнала.
Этот проект требует только MongoDB, и вы можете запустить его с помощью docker-compose .
cd deployments && docker-compose up -d
cd cmd/koochooloo/ && go build && ./koochooloocurl -X POST -d ' {"url": "https://elahe-dastan.github.io"} ' -H ' Content-Type: application/json ' 127.0.0.1:1378/api/urls
curl -L 127.0.0.1:1378/api/CKaniA checks.....................: 99.83% ✓ 2995 ✗ 5
data_received..............: 2.0 MB 64 kB/s
data_sent..................: 521 kB 17 kB/s
group_duration.............: avg=649.18ms min=153.18µs med=265.45ms max=30.95s p(90)=1.61s p(95)=2.06s
http_req_blocked...........: avg=14.12ms min=0s med=3µs max=1.65s p(90)=13µs p(95)=147.04µs
http_req_connecting........: avg=6.23ms min=0s med=0s max=1.36s p(90)=0s p(95)=0s
http_req_duration..........: avg=272.98ms min=0s med=127.99ms max=4.81s p(90)=830.93ms p(95)=1.29s
http_req_receiving.........: avg=125.23µs min=0s med=60µs max=11.21ms p(90)=228µs p(95)=363µs
http_req_sending...........: avg=50.78µs min=0s med=22µs max=7.28ms p(90)=86µs p(95)=138µs
http_req_tls_handshaking...: avg=7.86ms min=0s med=0s max=653.63ms p(90)=0s p(95)=0s
http_req_waiting...........: avg=272.8ms min=0s med=127.71ms max=4.81s p(90)=830.87ms p(95)=1.29s
http_reqs..................: 4000 129.093962/s
iteration_duration.........: avg=1.29s min=142.34ms med=1.04s max=30.97s p(90)=2.18s p(95)=2.64s
iterations.................: 1000 32.273491/s
vus........................: 100 min=100 max=100
vus_max....................: 100 min=100 max=100