Пишем REST API сервис на Go - УЛЬТИМАТИВНЫЙ гайд

  Рет қаралды 140,569

Николай Тузов — Golang

Николай Тузов — Golang

Күн бұрын

Пікірлер: 250
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
👾Мой канал в Telegram: t.me/ntuzov Пишу там новости, анонсы своих активностей и просто интересные мысли Также с его помощью я получаю от вас оперативный фидбэк по роликам - что нравится, что не нравится, какой ролик делать следующим и т.п. ❤ Если у вас есть желание поддержать развитие канала: Секретный телеграм-канал: - В рублях: t.me/+1UPXV_DGnG1mODJi - В евро: t.me/+hedI8LevYTc5MDM6 boosty.to/nikolay.tuzov www.patreon.com/tuzov
@idgalushko
@idgalushko 8 ай бұрын
Николай, спасибо огромное за ваш труд и творчество! Благодаря вам, научился создавать веб-сервисы, которые очень удобно масштабировать, рефакторить и поддерживать, пересаживать на любые базы данных и реализации кэша, а также подключать несколько серверов, реализующих различные протоколы обмена данными! А всё благодаря разделению общей архитектуры на слои и интерфейсам! Просто топ, ещё больше стал любить писать на Go благодаря вам!
@nikolay_tuzov
@nikolay_tuzov 8 ай бұрын
Рад, что помог ❤️ Всегда очень приятно видеть такие отзывы
@STAP2011
@STAP2011 Жыл бұрын
Приятно видеть полезные содержательные видео для новичков на великой Гошечке без всяких ужасностей - сразу к делу, качественно на уровне продакшн кода и без воды, уважаемо!
@wat4mon
@wat4mon Жыл бұрын
ЛУЧШЕЕ ЧТО МОЖЕТ БЫТЬ В СУББОТНЕЕ УТРО. СПАСИБО ОГРОМНОЕ ЗА КОНТЕНТ. ПРОСТО ЛУЧШИЙ!!!!
@paniciour
@paniciour Жыл бұрын
э, что угодно?..
@vitiok78
@vitiok78 Жыл бұрын
Только начал смотреть, но уже по содержанию вижу, что это золотое видео! Спасибо!
@ВасяДомин-ъ8п
@ВасяДомин-ъ8п 7 ай бұрын
Мужик, ты крут, спасибо тебе за такие видео. Действительно очень полезные!
@qwertyqwerty-q1w
@qwertyqwerty-q1w Жыл бұрын
На мой взгляд коду рано в реальное использование 1) неоправданно сложная структура проекта(было тяжело читать код) + сервис очень напоминает код node+express 2) явное отсутствие слоёв приложения 3) разделение интерфейсов для обращения к бд на отдельные операции??? 4) отстутсвие контекста в методах для работы с бд(если бд находится локально, это не значит, что с таймингами будет всё ок. Например при обращении к бд может быть нагрузка на диск 100% и запрос будет схлопнут таймаутом который указали при конфигурации http сервера, что является не лучшим решением) + в серьёзных сервисах конфигурируют таймауты под каждый слой 5) цитата: "изза одного единственного запроса хэндлера не должно приложение падать целиком". Полностью несогласен! Для такого приложения с простой логикой все запросы "одинаковые" и если у нас происходит гдето паника, значит она будет происхдить постоянно, а в таком случае приложение работать не должно(его надо чинить) + дефолтный хттп сервер сам отлавливает паники 6) приложение никак не валидирует урлы, такое чувство, что это не сокращатель урлов, а переосмысленный редис. 7) time.Now() используется без часового пояса 8) нету Readme и Swagger(пришлось лезть в код, чтобы понять как запускать сервис) 9) save_test.go:83 require.Equal(t, rr.Code, http.StatusOK) - если быть невнимательным, то создаст весёлую проблему 10) хэлсчек! Как минимум это первое что проверяют если с сервисом проблемы, лучше всего делать через вызов db.PingWithContext(ctx)
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Спасибо за фидбэк, но с большинством пунктов в корне не согласен: 1) очень абстрактное заявление, довольно субъективный. В чем конкретно сложность? Что именно тяжело читать? 2) В предыдущем пункте вы жаловались на сложность, а добавление слоёв сложность увеличит. Их потому и нет - чтобы не переусложнять приложение. На мой взгля, в подобное проекте можно прекрасно обойтись без них. Если вы с этим не согласны, можем обсудить - приведите примеры, в которых у нас будут проблемы из-за отсутствия слоёв? 3) Да, а что с этим не так? Если подход непонятен, смотрите мой ролик на эту тему (ссылка есть в описании) 4) Тут согласен, контексты стоило добавить, это мой промах 5) "если у нас происходит гдето паника, значит она будет происхдить постоянно" - абсолютно неверное утверждение. У нас есть тесты, а значит, как минимум, happy path и некоторые fail-кейсы будут работать. Если паника и появляется, то точно не во всех случаях. Так зачем падать всему приложению целиком? Чтобы перестать обрабатывать даже корректные запросы? Что нам это падение вообще даст? 6) Посмотрите внимательней, валидация урлов - это вообще единственный валидатор, который у нас есть (помимо required), в хэндлере Save. 7) А зачем нам часовой пояс? Вы точно смотрели ролик, и просто бегло про коду прошлись? Во всем проекте всего 2 точки использования данной функции: подсчет дельты и задание сида в рандомайзере. Для чего там часовой пояс? 8) Readme не помешал бы, согласен. Но это явно не must have фича для работы приложения в продакшене, а скорее помощь себе в будущем. 9) Не очень понял, о какой проблеме речь? 10) Да, тут согласен, стоило сделать что-то простенькое. Но вообще, полноценный мониторинг будем делать в отдельном ролике
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Если хотите обсудить подробней, приглашаю вас в наш чат Gopher Club (ссылка в описании). Приходите, подискутируем. Заодно и сообщество рассудит, кто из нас прав. Там присутствуют и гораздо более опытные коллеги, чем я.
@qwertyqwerty-q1w
@qwertyqwerty-q1w Жыл бұрын
@nikolay_tuzov 1) да, тяжело читается, хотя кода немного 2) я думаю большинство тех, кто смотрел видео это джун или тот кто хочет устроиться джуном, и на мой взгляд стоило бы показать как "правильно делать", потому что придут они на работу и начнут слой данных выпиливать ссылаясь на это видео). Если это попытка в хайлоад/уменьшение расхода памяти/времени отклика, то стоило бы и с остальным кодом то же самое делать Про проблему отсутствия слоёв, она возникнет когда захотите сменить бд, sqlite хороша, но когда нужно будет уходить от неё, то всплывёт проблема отсутствия слоя данных(возможно не такая острая как в серьёзных сервисах, где извращаются над запросами в целях оптимизаций, но будет, как минимум сейчас нет возможности вынести в конфиг тип базы для сервиса и переключиться например на редис или монгу) 3) ничего не имею против разделения интерфейсов, но для сервиса на пару таблиц ваш подход избыточен(возможно было бы лучше оставить как есть и обернуть их в общий интерфейс) 5) грубо говоря сервис каждый раз проходит одни и те же проверки и если передавая два набора валидных данных, в котором один успешно проходит, а второй падает в панике, то это говорит о серьёзной ошибке в коде, которую надо чинить, а не пытаться восстановить прилагу(возможно гдето данные сломались и тогда нет никакого смыслы хранить битые данные) 6) сорри, не заметил 7) сорри, привычка после работы с распределёнными сервисами, не актуально для одного инстанса 9) стоит почитать сигнатуру require.Equal() func Equal(t TestingT, expected interface{}, actual interface{}, msgAndArgs ...interface{}) {
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
@@qwertyqwerty-q1w 1) Я всё ещё не вижу конкретных аргументов - что именно там тяжело? Приведите пример того, как было бы легко в данном случае? 2) Такое ощущение, что у вас есть некое универсальное правило, какая архитектура правильная. А это не так, она сильно зависит от проекта. Писать пет-проект с кучей слоёв, которые там не пригодятся - НЕ правильно. И допускать оверинжениринг в пет-проектах, это тоже плохо. Это не попытка оптимизации производительности, это отсутствие бессмысленного повышения сложности проекта - кода меньше, он проще, понятней. 3) Не соглашусь с этим утверждением 5) А если в сервис приходит 99 запросов, и лишь 1 из них проблемный и ломает приложение? Нам нужно уронить сервис, чтобы он обрабатывал 0 запросов, пока мы чиним тот единственный проблемный? Вы действительно считаете это хорошим подходом? 7) дело даже не в распределенных сервисах, а в том, зачем вообще используется функция time.Now(). Если она нужна только для получения дельты времени, внутри одной и той же функции, то при чем тут распределенность? В распределенном сервисе я бы тоже не стал думать здесь о временных зонах 9) Я знаю сигнатуру, и всё ещё не понимаю, о какой конкретно проблеме речь.
@qwertyqwerty-q1w
@qwertyqwerty-q1w Жыл бұрын
@@nikolay_tuzov лучше вынесите обсуждение в канал
@oliverswanick4965
@oliverswanick4965 Жыл бұрын
Даешь видео про миграции!
@radikovichkz2470
@radikovichkz2470 Жыл бұрын
В golang нет миграций
@console.g
@console.g 9 ай бұрын
В Турцию можно мигрировать
@dovm5d
@dovm5d 9 ай бұрын
48:08 - mySQL как раз таки поддерживает стандартным драйвером. PostgreSql стандартным драйвером точно не поддерживает, надо в конец запроса добавлять RETURNING id и вместо экзека отправлять запрос через QueryRow
@unicoxr5tj417
@unicoxr5tj417 Жыл бұрын
даешь практику для народа! Таким видосам тока лайк
@y0oshi2
@y0oshi2 8 ай бұрын
круто объясняет и самое главное, наглядно все показывает на практике👌
@crazy_fedor
@crazy_fedor Жыл бұрын
Николай, материл от вас - просто супер. Выпустите пожалуйста видео про миграции! 🌷
@nikolay_tuzov
@nikolay_tuzov 11 ай бұрын
А что именно интеренсо про миграции услышать? Помимо того, что было показано в этом видео
@АлександрВасильев-в1е
@АлександрВасильев-в1е 11 ай бұрын
Отличный гайд, Николай. Очень познавательно и интересно смотреть твое творчество. Респект!
@purkhanov
@purkhanov 3 ай бұрын
Спасибо очень полезное видео ждем больше таких видео. Снимите видео про фреймворки го что лучше использовать
@altRU1st
@altRU1st Ай бұрын
Вот кстати, да, мне кажется, copilot лучше отключать особенно для тех кто начинает, а то он заведет в дебри, одно дело когда сам ошибся и при сборке увидел ошибку от компилятора, а другое дело когда Copilot что-то подсказал, ты согласился, а тебе надо было другое или не так, и ошибки вроде нет, или нет но она глубже, короче потом искать ее можно долго.
@ivmax96
@ivmax96 Жыл бұрын
Огромное спасибо! Таких видео очень не хватает, особенно на русском. Сегодня вечером просмотрю видео и сам пройду все шаги. У вас вижу GoLand, а я в vscode пишу. Но, думаю, из-за этого сложностей не будет.
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Сложностей быть не должно. IDE - это лишь вспомогательный инструмент. Можно хоть в блокноте писать =)
@paniciour
@paniciour Жыл бұрын
​@@nikolay_tuzov не, не можно) интеграция гита, бд, рефакторинг, навигация - у вскода из коробки ничего этого нет, можно обвешаться гирляндой расширений, но зачем если можно просто переактивировать голанд раз в месяц на диспозабл емейл 💀
@jojogay7297
@jojogay7297 Жыл бұрын
@@paniciour а че так можно реактивировать?
@paniciour
@paniciour Жыл бұрын
@@jojogay7297 я этого не говорил, меня взломали)
@yakomisar
@yakomisar Жыл бұрын
@@paniciourили neovim поставить, только выиграешь в долгосрок
@1amercat
@1amercat 5 ай бұрын
С go-gin и logrus чот как-то попроще и приятнее. Спасибо!)
@nikolay_tuzov
@nikolay_tuzov 5 ай бұрын
Возможно, просто привычней
@ThePirateHistory
@ThePirateHistory 11 ай бұрын
Было бы классно ещё понимать как описать то что ты сделал в комите, допустим сделали логер, он работает для теста вывели пару сообщений, как записать просто "Initialized logger" и всё, или допустим создали какую-то структуру, вывели возможно менять конфигурацию логера в конфиг файл
@svfastunov
@svfastunov Жыл бұрын
Очень классный и полезный материал. Темы по наблюдению за всем этим хозяйством не хватает.
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
По мониторингу точно будет отдельное видео. У меня уже есть материал, я хотел в этом видео о нем рассказать. Но потом решил всё же отдельно, т.к. ролик слишком большой получался.
@vitiok78
@vitiok78 Жыл бұрын
Последнее время я всё реже использую автоматические id в базе данных. Именно из-за того, что id может быть неизвестен сразу после вставки. Я генерирую uuid, который не полностью рандомный, а типа последовательный. Таким образом, я заранее знаю id, и этот id не так сильно влияет на производительность базы, т.к. он уже отсортирован. Да, такое поле увеличивает размер базы, но оно слишком удобное, чтобы от него отказаться.
@vasyarodionov1369
@vasyarodionov1369 7 ай бұрын
а как же метод returnid?
@vitiok78
@vitiok78 7 ай бұрын
@@vasyarodionov1369 Не всегда возможно использовать. Особенно, когда в проекте ORM какая-то используется
@vladosssss1088
@vladosssss1088 Жыл бұрын
Спасибо за такой отличный урок, впервые просмотрела урок до конца. Узнала очень много нового и полезного, очень помогают твои подробные объяснения что и для чего нужно. Спасибо
@hurricane-rus
@hurricane-rus 11 ай бұрын
Хорошее видео, разобрано много интересных подходов, спасибо. До хэндлеров было в целом понятно, потом объяснения пошли очень сжато и кратко, приходилось переслушивать 3-4 раза, чтобы стало понятно. Код хэндлеров очень плохо читается из-за кучи логов - может быть, их можно обработать как-то поэлегантнее? В будущих видео хочется как можно меньше моментов в стиле "просто добавьте сюда этот код, который я не буду объяснять" - по мне такой код лучше вообще не добавлять в проект (ну или потратить дополнительное время на его объяснение). P.S. Не понял, зачем нужно было делать столько лишних папок в проекте? (фактически каждый файл лежит в отдельной папке) Т.е., например, зачем папка sqlite в папке storage? Можно сразу storage.go кинуть в storage. Или в lib/logger папка sl кажется лишней - можно сразу sl.go кинуть в logger, и все. Если поудалять все эти лишние папки, дерево проекта будет намного меньше. Чем мне мешают эти дополнительные папки - они затрудняют ориентирование в проекте и сильно раздувают дерево проекта. А поскольку программист в основном читает код, то чем компактнее будут уложены файлы, тем лучше.
@МагомедКантаев-ж1о
@МагомедКантаев-ж1о 4 ай бұрын
Полный согл с папками. У меня это вызвало панику как новичку. От диссонанса я даже досмотреть не смог и разочаровался в том что я выбрал ГО. Но благо тебе стало немножко уютнее)
@galahad667
@galahad667 8 ай бұрын
Лучший канал по гошке на русском ютубе!!!
@artmon2004
@artmon2004 Жыл бұрын
Супер! Пробовал пройти cоревнование Codeforces на стажировку в OZON, занял 300 место из 900 примерно, народу тьма в Go идет))))))
@dmitriybogdanov6291
@dmitriybogdanov6291 Жыл бұрын
Спасибо за труд!
@AndrewYurchenko
@AndrewYurchenko Жыл бұрын
Блин. А в видео - это где можно увидеть? )) Хорошо, что уже не первый день обучалки смотрю и знаю о таких "выкрутасах от блогеров" - читать в надежде комменты. Но, все же. Это баг!!! )))
@АлександрРабушко-ц7о
@АлександрРабушко-ц7о Жыл бұрын
Спасибо огромное за контент!
@Iongjump
@Iongjump Жыл бұрын
Спасибо за контент ❤
@kotlinjava5228
@kotlinjava5228 Жыл бұрын
Большое спасибо за ролик,и уважение за флаг Казахстана на фоне!
@АлександрВарфоломеев-э2в
@АлександрВарфоломеев-э2в Жыл бұрын
Спасибо за контент!
@purplecorvette
@purplecorvette Жыл бұрын
почему не сетится CONFIG_PATH фатал печатает что конфиг пас не установлен(
@aleksandrpetrov3938
@aleksandrpetrov3938 8 ай бұрын
Видимо имеется ввиду что запускать мы будем основной скрипт так CONFIG_PATH=./config/local.yaml go run main.go - и у нас есть свобода выбора какой путь к конфигу указать. Если на проде, то файл уже другой просто указываем и всё
@Vanilla.Thunder
@Vanilla.Thunder 4 ай бұрын
@@aleksandrpetrov3938 Не получилось запустить с вашей командой, изменил путь, но насколько это правильно? CONFIG_PATH=../../config/local.yaml go run main.go
@simondiakov895
@simondiakov895 4 ай бұрын
CONFIG_PATH из окружения берётся, а значит его туда надо поместить в командной строке перед запуском приложения: $env:CONFIG_PATH = "C:\...\project_folder\config\local.yaml"
@dhdhdkfjgjdmf5277
@dhdhdkfjgjdmf5277 Ай бұрын
У меня тоже так выходило, из-за этого я каждый раз экспортировал CONFIG_PATH, но потом мне это надоело, и я просто прописал в MustLoad : defaultConfigPath := "/home/tamerlan/GolandProjects/first_project/config/local.yaml" if err := os.Setenv("CONFIG_PATH", defaultConfigPath); err != nil { fmt.Println("Error setting environment variable:", err) return nil } и после этого локально начало запускаться чики-пуки. Насчёт прода, я ещё не дошел до этой части видео. Кроме того у Николая как вы могли заметить в начале видео есть файл local.env, я не сталкивался с такими файлами до этого (сам ещё на джуна учусь, но рискну предположить, что дело как раз таки в этом файле
@ДанилКолоколов-у1в
@ДанилКолоколов-у1в 10 ай бұрын
Видео очень хорошее, спасибо автору! Если есть возможность, можно ещё видео про деплой не через гитхаб, а через гитлаб ci/cd? Было бы 🔥
@cartfpv4610
@cartfpv4610 Жыл бұрын
1. Rest коды не используютя по какой то причине? 2. Динамические/настраиваемые моки языком в принципе не поддерживаются? Все создавать в статике/ генерировать?
@Voxilar
@Voxilar 19 күн бұрын
У меня вопрос, как в этом коде выделять теги yaml: env: envDefault: А то у меня в vs code сплошная строка получается package config type config struct { Env string `yaml:"env" env:"ENV" envDefault:"development"` }
@mini_clop
@mini_clop Жыл бұрын
Утро наступило!
@RusFarFaz
@RusFarFaz Жыл бұрын
Хотелось бы про concurrence и паттерны их использования. Например воркеры, fan-in , fan-out
@alexeymatveev9031
@alexeymatveev9031 8 ай бұрын
Посмотрел анонс, но понял, что приснилось. Не может быть столько крутоты.
@nikolay_tuzov
@nikolay_tuzov 7 ай бұрын
Сон наяву)
@ginger.samurai
@ginger.samurai Жыл бұрын
ЛУЧШИЙ
@Evg2002
@Evg2002 9 ай бұрын
спасибо, все очень круто!
@grigorym6107
@grigorym6107 Жыл бұрын
Подскажите пожалуйста, где вы устанавливаете значение CONFIG_PATH, чтобы потом читать его в файле internal/config/config.go, в строке configPath := os.Getenv("CONFIG_PATH")?
@gorsaroyan1060
@gorsaroyan1060 Жыл бұрын
Я запускаю так CONFIG_PATH=./config/local.yaml go run ./...
@alonewalker4932
@alonewalker4932 11 ай бұрын
Привет! Если ты разобрался с этим подскажи пожалуйста решение данной проблемы
@EgrNegr-chugun
@EgrNegr-chugun 9 ай бұрын
вы это делаете в терминале? @@gorsaroyan1060
@EgrNegr-chugun
@EgrNegr-chugun 9 ай бұрын
а это в терминале вы запускаете или где? @@gorsaroyan1060
@TheWorpX
@TheWorpX 8 ай бұрын
Я пофиксил таким образом (GoLand) Там где у нас есть ранер, тыкаем на стрелочку и тыкаем Edit Configurations Там у нас высветиться автоматически созданые ранер (это когда на зеленую стрелочку play нажимаешь около func main) Находим там поле Environment и прописываем туда CONFIG_PATH=./config/local.yaml Тыкаем Apply и стартуем
@vitiok78
@vitiok78 Жыл бұрын
Миграции очень нужны!
@soundcloudlover
@soundcloudlover Жыл бұрын
Будут ли видео по внутренностям go? А именно как точно устроена сборка мусора и как работает планировщик/аллокаторы? спасибо
@dizelvinable
@dizelvinable Жыл бұрын
Ух, супер!
@jimshtepa5423
@jimshtepa5423 Жыл бұрын
какую команду выполнили когда запустили программу в самом начале чтобы убедиться что все конфиг настройки были учтены? просто git init? или что то еще
@dn.kolesnikov
@dn.kolesnikov Жыл бұрын
Про slog видео будет в паблике? Интересно твоё видение его кастомизации и настройки.
@samoiloff90
@samoiloff90 Жыл бұрын
Просто огонь контент
@Roman-tm6qp
@Roman-tm6qp 6 ай бұрын
2:00:10 - насколько правильно передавать объект storage в хендлер роута? Не будет ли лучше это делать внутри хендлера (там где мы работаем с базой непосредственно)?
@mrfofaify
@mrfofaify Жыл бұрын
Сделайте видео с проектом по чистой архитектуре
@vladk7631
@vladk7631 Ай бұрын
Казахстан алга!!!!
@ВячеславЖувага-ю3ч
@ВячеславЖувага-ю3ч 4 ай бұрын
Добрый день! Про миграции уже создано видео? Не вижу на канале, а тема - очень интересная. Заранее благодарю!
@nikolay_tuzov
@nikolay_tuzov 4 ай бұрын
Привет, пока нет
@ThePirateHistory
@ThePirateHistory 11 ай бұрын
Решил делать как говорили в начале чтобы было аля своё, решил добавил логер в ямл конфиг, сделал как с http_server, всё работает за исключение что уровень логера с нулём просто не берёт выдаёт ошибку, ставлю допустим -4(дебагинг) всё работает, всё выводится как по видео, но если в кфг ямла ставлю 0 то всё, сам struct логера уровень логера int8
@inspired_by_space
@inspired_by_space 6 ай бұрын
Подскажите пожалуйста, почему в каждом методе Storage , вы пересоздаете подготовленные выражения (stmt) при каждом вызове метода, а не ,например создаете специальный метод в котором эти выражения будут подготавливаться и уже потом сразу использоваться в методах?
@alpenveg
@alpenveg Жыл бұрын
Спасибо за видос!
@dimmodddimmodd7199
@dimmodddimmodd7199 Жыл бұрын
Спасибо!
@georgiy_kulagin
@georgiy_kulagin Жыл бұрын
кайф
@jimshtepa5423
@jimshtepa5423 Жыл бұрын
в самом начале когда вы перешли к написанию кода и начали создавать папку cmd, вы использовали какой то пакет который генерирует шаблон для проекта? (типа как vitejs на javascript чтобы собрать шаблон проекта?). или вы сами создали паку url-shortener и внутри создали файлы вручную?
@tyapka
@tyapka 7 ай бұрын
Запрос на следующие уроки: - Как сделать асинхронную работу (пусть запускается через API вызов) в кластере, чтоб она 1) по какому-то ключу была только одна во всем кластере и 2) востанавливалась после падения сервера (можно с использованием ZooKepera или etcd) - Реал лайф пример работы с Dragonboat (RAFT либа).
@ВасяДомин-ъ8п
@ВасяДомин-ъ8п 7 ай бұрын
Отличное видео, но я так и не понял 1:43:30 почему надо писать tc := tc?
@williba100n5
@williba100n5 9 ай бұрын
Спасибо
@paniciour
@paniciour Жыл бұрын
Го видик по b-tree?) Не, го целый видик по имплементации базки с конкаренси, б-трии и фильтром блума!
@alexsandr9444
@alexsandr9444 Жыл бұрын
Да нужно про миграции
@8Sapphire8
@8Sapphire8 Жыл бұрын
Ролик бесценный что тут сказать. 5 из 5
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Спасибо ❤️
@Влэйпи
@Влэйпи 2 ай бұрын
у меня configPath := os.Getenv("CONFIG_PATH") возвращает пустую строку, потом соответственно выходит ошибка, в чем проблема не могу понять
@ТимурГильмутдинов-з3ч
@ТимурГильмутдинов-з3ч 2 ай бұрын
Аналогично, прописал в переменные среды и как пользователя и в системные переменные, также выводит пустую строку и ошибку.
@ТимурГильмутдинов-з3ч
@ТимурГильмутдинов-з3ч 2 ай бұрын
В качестве временной меры, чтобы двигаться дальше, заменил configPath := os.Getenv("CONFIG_PATH") на configPath := "C:/путь.../config/local.yaml". Заработало, db создалась. Почему всё-таки configPath := os.Getenv("CONFIG_PATH") возвращает пустую строку, а затем выходит ошибка, тоже так и не понял.
@ТимурГильмутдинов-з3ч
@ТимурГильмутдинов-з3ч 2 ай бұрын
Возможно связано с использованием виндоуз как-то
@ТимофейЁлкин-о9е
@ТимофейЁлкин-о9е Жыл бұрын
Я ещё не досмотрел, но вопрос, пока не забыл: как сюда подключить ещё и обработку параметров запуска из консоли (ключей типа --config)? Как их правильно с обработкой конфига дружить?
@alexobzor
@alexobzor Жыл бұрын
По поводу тестирования хэндлера save, почему запрос NewRequest берётся из библиотеки http, а не httptest? В основе теста же лежит именно Response Recorder, соответственно не создаётся сервера на loop back, ну и нужды в реальном запросе нет, тогда почему бы не юзать из httptest?
@yakomisar
@yakomisar Жыл бұрын
Прикольно, но отдельный ролик для https ты маханул конечно. Self-signed сертификат прям с Голанг идет из коробки.
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Self-signed не совсем то. Я обычно через Cloud Flare делаю, но при этом сильно тоже не заморачиваюсь, выбираю гибридный вариант (от клиента до CF по https, от CF до моего сервиса http) Заодно там можно будет показать, как настроить работу с доменом. Но в целом да, ролик получится короткий и простенький.
@bsprspktvnk
@bsprspktvnk Жыл бұрын
вместо op можно в логгерах включить caller чтоб показывало файл с конкретной строкой
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Это дорогостоящая операция, поэтому оно не всегда того стоит.
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Хотя, это не чрезвычайно дорого, и каких-то случаях допустимо, согласен. К примеру, обычно логгеры добавляют стек вызовов в случае Error-сообщений
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Кроме того, видеть имя функции вместо номера строки удобней. Потому что код может измениться, и номера строк сдвинутся. Придется выяснять, какая версия была задеплоена и т.п.
@bsprspktvnk
@bsprspktvnk Жыл бұрын
​@@nikolay_tuzov ну не знаю, можно и выводить какая функция выполняется, насчёт накладных расходов - не знаю, в zerolog\zap врубаю во время разработки или когда приложение на тестовом контуре
@paniciour
@paniciour Жыл бұрын
@@nikolay_tuzov op в upspin подсмотрел?) имхо полусомнительная приставка, тк вызывающий код и так знает название вызываемой функи, ему интереснее какой именно ее бит сбойнул. ты из каждой функи ретурнишь обернутые опом ошибки?
@ThePirateHistory
@ThePirateHistory 11 ай бұрын
1:14:09 как реализовать так чтобы наоборот, чтобы интерфейс был в отдельном файле в пакете sqlite. папка sqlite в том же месте что и у вас, затем внутри папка interfaces и там допустим save, и соответственно это надо как-то зарегистрировать в одноимённом файле пакета sqlite, как это сделать? Чтобы мы могли брать из одноименного файла sqlite и функцию save для сохранения url, а так же чтобы могли взять интерфейс в хандлере что в сервер, подскажите куда копать пожалуйста
@nikolay_tuzov
@nikolay_tuzov 11 ай бұрын
Советую все подобные вопросы писать в Gopher Club. Они довольно сложные, не для комментов.
@ThePirateHistory
@ThePirateHistory 11 ай бұрын
@@nikolay_tuzov Тг хорошо, но безумно не удобно, в тг просто 1 чат, и там люди общаются о своём, ты что-то запостишь какой-то вопрос он почти моментом скроется, а спамить этим вопрос это плохо, даже просто реплаить по кд такое себе, лучше дискорд, там можно создать каналы, чтобы просто общения было отделено от тех вопросов. Но как помню или тут в начале видео или из тех что в описании, был такой момент что был интерфейс Users в котором были как раз таки все методы и они были в отдельных папках, и получается что туда вручную записываются, то в файле допустим по уроку sqlite будет интерфейс по типу Users в котором будут интерфейсы, но как это правильно называется чтобы лучше разобраться вроде понял а вроде не до конца. И если сможете, то подскажите как называется практика при которой такие вещи они регистрируется, чтобы был допустим интерфейс в котором можно запушить свой другой интерфейс, чтобы вручную всё не писать, чтобы не было сотни интерфейсов которые содержат интерфейсы которые ссылаются на интерфейсы. Допустим User User.signUpMethod(saveDefaultData) и потом можно в любом месте User.saveDefaultData('...', '...')
@bobmoclaat8965
@bobmoclaat8965 8 ай бұрын
Почему config_path не найден пишет? Зачем мы тогда local.yaml создавали
@quiqlerbeats5933
@quiqlerbeats5933 7 ай бұрын
Тебе нужно путь до него в переменной окружения указать
@Vanilla.Thunder
@Vanilla.Thunder 4 ай бұрын
Посмотри комментарии выше, там есть ответ
@dhdhdkfjgjdmf5277
@dhdhdkfjgjdmf5277 Ай бұрын
local.yaml просто устанавливает config, нужно же к самому config-у тоже path указать. Если хотите чтобы всё работало на автомате, просто пропишите path в MustLoad функцие. Если вы не ленивый человек то можите каждый раз перед запуском программы в терминале экспортировать CONFIG_PATH
@ivan42832
@ivan42832 6 ай бұрын
Отличный материал, Николай спасибо! Знакомлюсь с go первую неделю. Я правильно понимаю что реализовывать http апи это не специализация Го? По сравнению с другими языками по удобству и читаемости это прям боль, даже js/ts логичнее выглядит. При этом я уверен что Николай лучшие практики применял. Я в основном на php уже 10 лет разрабатываю так вот там бизнес логику и доступ к ней по http в разы удобнее, проще, быстрее реализовывать да и надежнее думаю. Но конечно куча других минусов по сравнению с Го. А вообще язык заинтересовал, для чегонибудь мелкого и быстрого отличчно подойдет
@eterline
@eterline 4 ай бұрын
язык и был сделан для быстрого написания микросервисов и бэка. Там у гугла целая история появления этого языка и почему c++ бе-бе. А на GO написан тот же Kubernetes к примеру, я бы не назвал это мелкой штукой.
@ivan42832
@ivan42832 4 ай бұрын
@@eterline Да согласен. Для системных вещей подходит отлично любого сложности, тот же Линукс например вообще на Си написан, даже не на плюсах. А вот для сложной бизнес логики, автоматизации бизнес процессов мне показался не лучший инструмент.
@eleimt
@eleimt Жыл бұрын
подскажите, про миграции есть видео?
@danilakhtarov
@danilakhtarov 10 ай бұрын
Можно вместо alias использовать id и каждой цифре присвоить свой символ, а-ля base64
@Damir-nl6tf
@Damir-nl6tf 11 ай бұрын
Здравствуйте! Только начал изучать Go, хотелось бы узнать, то что пишет Николай в этом видео, обычно пишут Джуны Миддлы или Сеньоры? Спасибо всем за ответы!
@ГеннадийСамойлов-с4ю
@ГеннадийСамойлов-с4ю 9 ай бұрын
ждём, бро. Но думаю без подобных проектов на тебя HR даже не посмотрят
@Daloshka
@Daloshka 9 ай бұрын
export CONFIG_PATH=./config/local.yaml
@ФедорМакеев-й5ю
@ФедорМакеев-й5ю 5 ай бұрын
я так понимаю, сокращатель ссылок это hello world в мире го-разработки?
@madbad1310
@madbad1310 Жыл бұрын
Николай, уже октябрь. Где анонсированное отдельное видео по log/slog ? )
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Работы много, на видео очень мало времени остаётся. Но всё будет, планы в силе) Точную дату пока не могу назвать
@madbad1310
@madbad1310 Жыл бұрын
@@nikolay_tuzov Николай, у вас очень полезные видео. В любом случае, спасибо вам большое.
@valitovgaziz
@valitovgaziz 3 ай бұрын
Chi лучше чем Gin? Почему?
@datokhojava6421
@datokhojava6421 Жыл бұрын
в ОП ubuntu имеет значение где я создам папку?
@alexsandr9444
@alexsandr9444 Жыл бұрын
Привет спасибо за видео)Скажи а как задается "CONFIG_PATH" в окружение?
@boomy842
@boomy842 Жыл бұрын
Если ты на линуксе, то export CONFIG_PATH= Если на виндовс то set CONFIG_PATH=
@kirillgrossberg6950
@kirillgrossberg6950 Жыл бұрын
@@boomy842 Я правильно понял, тут получается set CONFIG_PATH=./config/local.yaml go run .\cmd\shrt\main.go ?
@EgrNegr-chugun
@EgrNegr-chugun 9 ай бұрын
а это надо в терминал писать или куда? @@boomy842
@ГорацийОктавий
@ГорацийОктавий Жыл бұрын
38:39 почему используется log.Error и Os.Exit, экзит же насколько я понимаю отменяет все defer. Не лучше ли тут кидать панику?
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Да, согласен, os.Exit может быть не лучшим вариантом, если используется defer. Тут нужно быть аккуратным.
@СергейИванов-ы7ч5ы
@СергейИванов-ы7ч5ы Жыл бұрын
@@nikolay_tuzov прибивать пустым мешком все открытые ресурсы - самый дубовый вариант
@anmill
@anmill Жыл бұрын
Ролик про миграции - плизззз!
@vladimireliseev7602
@vladimireliseev7602 Жыл бұрын
Здравствуйте, Николай! Благодарю за видео! Хотелось бы узнать - почему Вы возвращаете именно ссылку на конфиг, а не значение из функции MustLoad?
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Поправлю - указатель, а не ссылку* Вообще, это тема для частых дискуссий - возвращать указатель или значение. У обоих вариантов есть свои плюсы и минусы, но в большинстве случаев разницы почти нет. Если возвращаем значение, то при возврате и передаче мы каждый раз будем копировать все значения структуры. Зато в случае указателя можем накосячить с разыменованием.
@vladimireliseev7602
@vladimireliseev7602 Жыл бұрын
@@nikolay_tuzov благодарю!
@deuse7222
@deuse7222 Жыл бұрын
Код по работе с БД и сетью же работает в один поток синхронно, если не ошибаюсь. В продакшен коде стоит сразу писать через горутины?
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Нет, обычно в БД не ходят асинхронно, тк смысла нет - без похода туда обычно нечего делать дальше. А сам запрос обрабатывается в отдельной горутине и так
@weareneverdie4890
@weareneverdie4890 6 күн бұрын
почему вы выбрали chi, а не gin?
@nikolay_tuzov
@nikolay_tuzov 5 күн бұрын
Более легковесный, полная совместимость с http из стандартной библиотеки. Вот тут обсуждали: t.me/ntuzov/218
@kodikoff
@kodikoff Жыл бұрын
Очень ждём миграции
@MrLotrus
@MrLotrus Жыл бұрын
Насколько распространена практика хранения констант с названием и путем функций для логирования? Выглядит как возможная мина и гемор при рефакторинге. Другого способа нет? А если получать в рантайме это считается плохой практикой?
@ultrasmork6537
@ultrasmork6537 4 ай бұрын
Ну я не буду писать комментарий по поводу видео, я просто скопирую его и выпущу пару статей там пару пуков тут и скажу, что нормально всё, во если хош копируй на здоровье
@ТимофейЁлкин-о9е
@ТимофейЁлкин-о9е Жыл бұрын
19:10 А почему нельзя сначала проинициализировать логгер? Как принято вообще?
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Потому что мы инициализируем логгер различными способами, в зависимости от текущего конфига. Получается, для инициализации логгера нужно сначала получить конфиг.
@НикитаКуликов-ч4с
@НикитаКуликов-ч4с Жыл бұрын
Спасибо за видео! Если у storage'a и URLSaver'a будут немного отличаться сигнатуры методов, то где описывать адаптер?
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
А зачем им отличаться? Их сигнатура должна совпадать. Может, такое и бывает, но я не сталкивался.
@НикитаКуликов-ч4с
@НикитаКуликов-ч4с Жыл бұрын
@@nikolay_tuzov если например сторедж в другом пакете, не логично же интерфейс по месту использования подстраивать под этот сторедж🤔
@sanchosplay9892
@sanchosplay9892 Ай бұрын
21:33 Уже второй день пытаюсь пофиксить ошибку "CONFIG_PATH is not set". Понимаю, что скорее всего проблема в том, что local.yaml не передается в CONFIG_PATH. Пробовал команды set CONFIG_PATH=local.yaml как угодно. И полный путь передавал и из разных папок вызывал, ничего не помогает, как починить?
@DenissDivine
@DenissDivine Ай бұрын
я сделал так: в корневой папке создал файл ".env" и внутри написал -> CONFIG_PATH="./config/local.yaml" в main.go перед MustLoad() -> err := godotenv.Load() if err != nil { log.Fatalf("Error loading .env file") }
@sanchosplay9892
@sanchosplay9892 Ай бұрын
На случай если у кого-то возникла такая же проблема, то в терминале пишется SETX CONFIG_PATH "полный путь до файла". 2 способ. Win+x -> система -> дополнительные параметры системы -> Переменные среды. В переменные среды для пользователя Создать. Имя "CONFIG_PATH", значение - полный путь до файла
@qoonmax
@qoonmax 6 ай бұрын
В чем смысл использовать файл конфига? Почему нельзя ограничится env + дефолтные значения в env-default. Выглядит как лишний слой.
@petery6775
@petery6775 Жыл бұрын
подскажи, а чт оу тебя за тема и шрифт ?
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Всё стандартное для IDE GoLand. В видео я использую presentation mode
@jordenskraften8273
@jordenskraften8273 Жыл бұрын
Будет ли что-то по golang+graphQL?
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Возможно, будет. Но пока есть более важные и интересные темы на очереди
@Daloshka
@Daloshka 9 ай бұрын
1ч 42 мин смотрю уже 8ч. Очень годный видос. Не понравилось тольок что во время написания кода, его не было, просто копипаст
@nursaidimanbay9446
@nursaidimanbay9446 3 ай бұрын
21:30 , у меня выходила ошибка CONFIG_PATH is not set, в итоге я добавил переменную в функцию MustLoad переменную configPath = "./config/local.yaml", тупо чтобы продолжить смотреть урок, может кому то поможет
@user-mc4ju1hd3d
@user-mc4ju1hd3d 3 ай бұрын
Спасибо
@ТимурГильмутдинов-з3ч
@ТимурГильмутдинов-з3ч 2 ай бұрын
тоже так сделал, оказалось не только я)
@PlayGameToday
@PlayGameToday Жыл бұрын
Привет, как называется модель кресла твоя? )
@Vanilla.Thunder
@Vanilla.Thunder 4 ай бұрын
Похожа на DXRacer Air, но это не точно
@Trapmaloj
@Trapmaloj 7 ай бұрын
Подсобите кто сможет, сделал 1:1 но падает на этапе деплоя в VM, говорит неправильный ключ
@batyrakpanbet6292
@batyrakpanbet6292 Жыл бұрын
Видос шикарный, долго искал для практики. Сзадий флаг Казахстана?)
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Да)
@technozavrr
@technozavrr 7 ай бұрын
Поцаны на ларке все это за 15 минут сделают Когда уже фреймворк будет нормальный на гошке? Был бы опыт побольше, сам бы написал уже
@obey-onekenobi2818
@obey-onekenobi2818 10 ай бұрын
насчет discard logger. мб было бы легче в тесте создать логгер как slog.New(slog.NewJSONHandler(io.Discard, nil)), тогда бы не пришлось пустой логер писать
@АртёмКапитонов-ц9у
@АртёмКапитонов-ц9у Жыл бұрын
я возможно что то незаметил... но тут 2 слоя.. где usecases? прям из handler вызывать функции storage.. как то мне кажется не чисто
@paniciour
@paniciour Жыл бұрын
будь прагматичнее, если юзкейс дергает бд и ничего больше, то зачем плодить слои ради слоев
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Кажется, что в проектах такого уровня слишком много слоёв будет скорее вредно. Но это дискутивная тема, вряд ли тут есть однозначный ответ.
@nikolay_tuzov
@nikolay_tuzov Жыл бұрын
Для иллюстрации приведу обратную крайность. В ООП языках порой встречаются люди, которые прочитали книгу по паттернам, и в первых своих проектах пытаются реализовать сразу все эти паттерны. Получается нечто ужасное и сложное в поддержке. Это называется - оверинжиниринг. С опытом же начинаешь лучше искать баланс между простотой, практичностью
@AndrewYurchenko
@AndrewYurchenko Жыл бұрын
Блин, сел осваивать язык. Пока ищу, что можно тупо повторить, попутно въезжая в смысл. А тут роутер не стандарт... Хотелось бы пока с тем, что из коробки предоставляется разобраться. Но, что поделать... По любому благодарность!
@ГеннадийСамойлов-с4ю
@ГеннадийСамойлов-с4ю 10 ай бұрын
как успехи броу? похожая сейчас ситуация у меня)
@AndrewYurchenko
@AndrewYurchenko 10 ай бұрын
@@ГеннадийСамойлов-с4ю на тот момент отложил изучение Go, узнал про Rust. На нем освоил написание API. Но, за неимением вакансий и пока скудный спрос на рынке, вот попутно решил опять и Go добивать. После Rust намного легче вроде теперь заходит. Во всяком случае понимание работы с памятью там пришлось намного лучше освоить. Но, пока именно по Go сказать нечего. Как только доберусь до реализации, отпишусь. 👍
@ГеннадийСамойлов-с4ю
@ГеннадийСамойлов-с4ю 10 ай бұрын
@@AndrewYurchenko в путь )
Twin Telepathy Challenge!
00:23
Stokes Twins
Рет қаралды 84 МЛН
ТЮРЕМЩИК В БОКСЕ! #shorts
00:58
HARD_MMA
Рет қаралды 2,5 МЛН
Long Nails 💅🏻 #shorts
00:50
Mr DegrEE
Рет қаралды 11 МЛН
What type of pedestrian are you?😄 #tiktok #elsarca
00:28
Elsa Arca
Рет қаралды 31 МЛН
Делаем диаграмму с помощью нейросети!
3:03
JWT авторизация. Основы JWT - механизма.
6:45
Хочу вАйти
Рет қаралды 17 М.
Как на самом деле устроены каналы в Golang? | Golang channels internals
41:31
GoLang Slice в деталях, простым языком
32:09
Николай Тузов — Golang
Рет қаралды 89 М.
Twin Telepathy Challenge!
00:23
Stokes Twins
Рет қаралды 84 МЛН