Комментарии 25
Однако при поиске информации и учебных материалов он может отпугивать.
Ваш материал больше отпугивает, чем уже существующая информация.
Вместо того, чтобы переосмыслить своё мышление и писать на Go, вы свои .NET привычки просто затащили в другую среду и получилось это
Переосмыслить свое мышление и писать на Go для меня звучит слишком абстрактно, вы можете указать какие моменты, вы считаете неправильными и я бы с удовольствием для себя, что-то подчеркнул.
А просто в очередной раз слышать про переключение мышление, делу не поможет. Для меня язык программирования всего-лишь инструмент и я стараюсь привести решение, к общему формату, которое будет понятно большому числу разработчиков.
Я параллельно работая на .NET стараюсь изучать Go и достаточно сложно просто взять, выкинуть весь предыдущий опыт и начать писать "правильно". По-этому сначала делаю шаблон по классике, а в дальнейшем буду разбирать и что-то улучшать и мне вот в свое время не хватало таких статей, чтобы в целом понять.
Так же как и вы перешла, и тоже сначала пробовала ООП практики по привычке использовать. В общем наверное можно и так, но можно попробовать по другому. Что помогло мне это прежде всего чтение исходников стандартной библиотеки и на английском статьи и видео от William Kennedy. Ещё можно почитать например "Функциональное мышление" или что-то похожее, чтобы обновить подход (или как выше писали переосмыслить мышление).
Для меня язык программирования всего-лишь инструмент
Пила и молоток - тоже инструменты, но вы вместо того чтобы забивать гвоздь молотком пытаетесь им пилить, потому что "стараетесь привести решение к общему формату"
Любым инструментом надо тоже уметь пользоваться. И это касается не только Go, но и другого языка.
которое будет понятно большому числу разработчиков
Оно не будет понятно никому кроме вас и, возможно, других людей, которые один раз выучили программирование по гайдам для .NET и решили, что программирование - это только так.
В итоге, вы не пишете микросервисы на Go, вы пишете микросервисы, пытаясь натянуть синтаксис Go на парадигмы .NET.
А просто в очередной раз слышать про переключение мышление, делу не поможет.
Какому делу? Научить вас использовать инструмент? Так это ваше дело, а не кого-либо ещё. Только вот если вы будете писать так в Go проекте, который разрабатывают люди, которые действительно используют Go, то как минимум, на вас будут косо смотреть.
вы можете указать какие моменты, вы считаете неправильными и я бы с удовольствием для себя, что-то подчеркнул
Почитайте Effective Go, к примеру.
Уже с первых строк становится понятно, что вы используете пакеты как аналог классов, чтобы покрыть отсутствие инкапсуляции на уровне (отсутствующих) классов. Проблема в том, что Go - это не объектно-ориентированный язык.
Плюс вы сразу гвоздями прибили проект к определённой структуре, хотя в этом абсолютно никакой необходимости нет. Можно без проблем выделять сущности в отдельные структуры внутри одного пакета, пока у вас не появляется необходимости в дополнительном ограничении. Вы же не библиотеку пишете, а сервис, где единственный потребитель программных интерфейсов между сущностями - это сам сервис.
Пакеты с одним файлом в них - это антипаттерн, который больше мешает, чем помогает.
Кучу пакетов втянули просто потому что. Никак не поясняя необходимость, опять же скорее всего потому что вы привыкли к тому, что это так делается в .NET и несмотря на то, что функционал некоторых пакетов есть в стандартной библиотеке.
Пила и молоток - тоже инструменты, но вы вместо того чтобы забивать гвоздь молотком пытаетесь им пилить, потому что "стараетесь привести решение к общему формату"
Любым инструментом надо тоже уметь пользоваться. И это касается не только Go, но и другого языка.
Не совсем согласен с данным примером. Если есть какие-то паттерны и подходы ничто не мешает им ложится на множество языков. Go не такой уже и особенной, что на нем все нужно делать, как вы указали.
Оно не будет понятно никому кроме вас и, возможно, других людей, которые один раз выучили программирование по гайдам для .NET и решили, что программирование - это только так.
В итоге, вы не пишете микросервисы на Go, вы пишете микросервисы, пытаясь натянуть синтаксис Go на парадигмы .NET.
Причем тут выучили по гайдам. Есть определенная структура построения приложения для того, чтобы когда приходили новые разработчики, видели примерно тоже самое, что и на своей предыдущей работе. Все равно должна быть какая-то структура
Почитайте Effective Go, к примеру.
Благодарю изучу, но в целом тут общее описания синтаксиса языка без структуры.
Проблема в том, что Go - это не объектно-ориентированный язык.
Тут сложно сказать, все-таки язык содержит в себе объектно-ориентированные признаки, которые можно и когда требуется нужно использовать. Мы же не на чистом си пишем, где только одни функции и все
Плюс вы сразу гвоздями прибили проект к определённой структуре, хотя в этом абсолютно никакой необходимости нет. Можно без проблем выделять сущности в отдельные структуры внутри одного пакета, пока у вас не появляется необходимости в дополнительном ограничении.
С этим я согласен, что нужно пересмотреть раскидывание по пакетам
Если есть какие-то паттерны и подходы ничто не мешает им ложится на множество языков.
Если у вас есть паттерны, которые были спроектированы дедами для ООП, это очень даже мешает их использовать для языков, в которых нет ООП.
Go не такой уже и особенной, что на нем все нужно делать, как вы указали.
В том и дело, что я не говорю, как надо делать в каких-то конкретных ситуациях, я говорю, что изучая новую технологию, нужно проявлять гибкость ума, чтобы писать идиоматичный код, который будет понятен и привычен не только вам.
Любой инструмент имеет свои особенности, с которыми надо уметь работать. Если бы человек, который всю жизнь писал на C++ начал писать на .NET так, как он привык, то вы бы наверняка смотрели на код и думали: ну какой же чудак, ну кто так пишет.
Есть определенная структура построения приложения
Если вы имеете в виду структуру пакетов и директорий, то в документации языка нет ни слова о какой-то особой структуре проектов на Go.
Если речь о том, что "микросервис" какие-то определенные типы должен собой представлять - тут тоже мимо. Каждый пилит то, во что горазд и то, что нужно для конкретного проекта. Не говоря уже о том, что даже готовые фреймворки между собой не совместимы.
В итоге ваша "определённая структура" - это такая же незнакомая для других разработчиков структура, как и любая другая. Потому что никакого стандарта, которому должны следовать все, не существует.
Тут возможно, что язык молодой и еще появиться какая-то структурированность) В целом я согласен, что не нужно писать .NET, как на С++ если вы переходите на другой стек.
Все равно в целом нужно видимо больше времени, чтобы подстроиться под новый инструмент. Так что не буду тут спорить, так не являюсь опытным в гоу разработке, просто для себя изучаю и разбираю, почему он так популярен)
Так зачем с .net на go переходить?
Вариантов думаю масса и самый главный, который интересует большинство, что больше платят)
А так как я понял область применения, что из-за того, что он компилируемый и занимает мало место. На нем пишут всякое ПО для устройств, умной колонки, чтобы было возможно быстро заслать обновление.
Также делать классические API Crud сервисы, где требуется высокая производительность и также всякие потоковые штуки, трансляции видео.
Ну и в целом интересно что-то новое изучить
Также делать классические API Crud сервисы, где требуется высокая производительность и также всякие потоковые штуки, трансляции видео.
Это причина перейти с .NET на Go?
А так как я понял область применения, что из-за того, что он компилируемый и занимает мало место.
У вас видимо свой интернет. Если бы вы посмотрели размер вашего же бинарника, на основе кода для которого вы статью написали, то заметили бы, что он очень большой.
Один только runtime для hello world будет весить около 3-4мб. Это очень много и на Go пишут точно не из-за малого размера бинарников. Да, есть tinygo, но это не совсем Go и поведение программ может отличаться. Ну и он не очень-то и популярный за пределами DIY.
Также делать классические API Crud сервисы, где требуется высокая производительность и также всякие потоковые штуки, трансляции видео.
Если в такие программы пихать рефлексию не задумываясь, как вы делаете, то высокой производительности можно и не ожидать.
Вам лишь бы поспорить)
Про размер файла я не сравнивал со своим шаблоном микросервиса, а просто отвечал про области применения и где-то читал статью, как после перехода с Java размер бинарника был значительно меньше. Все равно даже если 3-4 мб много, на джаве вероятно будет весить больше.
А что я пихал из рефлексии? Просто добавил DI контейнер, нужны все-таки объективные замеры на сколько падает производительность, если использовать данный пакет
И в целом статья не почему стоит перейти на Go, а позволить потыкать что-то посмотреть в разрезе, как было на исходном языке с классическим ООП.
А так как я понял область применения, что из-за того, что он компилируемый и занимает мало место
В .Net сейчас AOT есть, тоже позволяет собрать небольшой бинарик.
Я вот тоже когда-то переходил из .NET в Go.
Несколько случайных замечаний:
- Название модуля в go.mod: обычно оно не src, а github.com/blahblah/blahblahblah. Это имеет значение, если кто-то будет импортировать ваш код. И совсем не обязательно помещать весь код в src.
- Вы начали использовать пакет internal для кода, который не должен переиспользоваться вне проекта, но при этом по какой-то загадочной причине контроллер и роутер не попадают в internal. По-хорошему, практически весь код, кроме main, может (и должен) быть в internal.
- Я очень понимаю желание использовать DI-контейнеры после многолетнего опыта работы с .NET, но по сути для микросервисов (если они, конечно, микро) большой пользы они не приносят - достаточно просто построить дерево зависимостей вручную.
- Если уж использовать ООП, то зависимости контроллеров, роутеров итп должны быть от интерфейсов, а не от реализаций. Ну, и тестов нет :-( Зачем городить многослойность контроллер-сервис-репозиторий, если нет ни бизнес-логики, ни доменной модели, ни тестов? А если и делать многослойную архитектуру (с расчетом, что когда-то микросервис станет гигантским монолитом), то почему вдруг сервис зависит от моделей API?
- Зачем экспортировать все поля в структурах таких, как Router, ControllerRoute, Server?
- В методе CreateBook контроллера отсутствует обработка ошибок - ошибки попросту игнорируются, что нехорошо. То же в методе Run сервера, который по-хорошему должен был бы возвращать ошибку.
- В методе getEnvAsInt: код на Go читается гораздо удобнее, если сверху вниз - happy path, магистральный сценарий, а все if обрабатывают ошибочные ситуации. Если поменять инвертировать if err == nil, чтобы стало if err != nil, то код станет каноничнее.
Удачи!
Благодарю за подробный ответ)
Название модуля в go.mod: обычно оно не src, а github.com/blahblah/blahblahblah. Это имеет значение, если кто-то будет импортировать ваш код. И совсем не обязательно помещать весь код в src.
Это важный момент, спасибо на будущее запишу себе!
Я очень понимаю желание использовать DI-контейнеры после многолетнего опыта работы с .NET, но по сути для микросервисов (если они, конечно, микро) большой пользы они не приносят - достаточно просто построить дерево зависимостей вручную.
Да после .NET очень тянет к DI контейнерам, но согласен, что тут можно обойтись без этого, чтобы лишний раз все не прописывать
Вы начали использовать пакет internal для кода, который не должен переиспользоваться вне проекта, но при этом по какой-то загадочной причине контроллер и роутер не попадают в internal. По-хорошему, практически весь код, кроме main, может (и должен) быть в internal.
Понял, с этим тоже согласен. В принципе наверное у микросервиса можно вынести в пакет, только какие-нибудь контракты, но нужно ли это в гоу)
По валидации параметров я еще не добавлял, хотел далее. Остальные ваще, спасибо, что описали использую для того, чтобы к следующей статье подредактировать проект.
Ещё про хотелось бы дополнить про internal, не обязательно весь код в нём хранить, в нем нужно хранить код самого проекта, что не будет импортироваться в другой проект, если есть код, который вы собираетесь использовать в другой проект, хорошей практикой будет его хранить в pkg, так вы сразу обозначите, что этот код может использовать кто то ещё
Платят чуть больше в среднем процентов на 10-20%. Мне кажется, если цель поднять зарплату просто чуть дольше поискать вакансию на .NET.
На больших цифрах так вообще не очень интересно. Вот вам сильно критично получать 400к или 330к условно?
В добавок учтите, что статистика дело такое, даже если в Go платят чуть больше, вы можете вполне залутать низ рынка, потому что у вас опыта на Go мало.
Go отличный, но мотивация плохая. Как известно, лучший язык который нужно изучать для роста зарплаты это английский.
между 400к и 330к разница колоссальная, т.к 250к (подставьте свою цифру) уходит на жизнь. итого разница в 2 раза на свои хотелки
Это уже хитрости сравнения. Конечно 330к и 400к это я большой разрыв взял, но даже если отталкиваться от него как от плохого сценария, то скажу так, задача "Выучить Go" это на несколько лет, на изучение нишевых задач и решений на Go, на получение интересного работодателю опыта.
Ведь на Go не платят за знание синтаксиса и умение написать микросервис с 2-мя крудами. Вероятно вы просядете по зарплате, пока не получите вкусный релевантный опыт. Следовательно часть дохода вы упускаете ежемесячно.
С маленьким опытом в других языках вы в Go никому не нужны, это 1000%. А с большим опытом в другом языке вы вероятно заработаете больше, нежели от смены стека.
Я думаю переход с другого языка и изучения с самого начала немного разные вещи. Ведь весь опыт работы на бекенде остается вместе с тобой и остальная инфраструктура не меняется. Типо контейнеры, куберы, кафки, реббиты. Да определенно нужно время, но я думаю вполне себе за пол года можно.
Разумеется это так. Но в глазах работодателя вы .Net Developer переходящий в Go, а не Golang developer. А чтобы претендовать на топ зарплат Go рынка, нужно как минимум год хорошего опыта на Go стеке.
У вас описка:got get "github.com/joho/godotenv"
Шаблон Go-микросервиса для начинающих от .NET разработчика. Часть 1