Почему вашему проекту нужен Go?

Почему вашему проекту нужен Go?

Пока одни языки программирования хвастаются сложностью и синтаксическим набором, Go делает ставку на прагматизм. И, как показывает практика, выигрывает.

Мы, команда агентства YouRich, создаем проекты на стыке маркетинга и IT. В этой статье мы объясним на языке бизнеса, какие преимущества имеет Go для разработки.

Google создал язык для людей

История Go началась с простой, но революционной идеи. В Google поняли: вместо того, чтобы обучать инженеров сложным конструкциям, можно создать язык, на котором надежный код смогут писать даже вчерашние выпускники. Нужен инструмент, который не требует долгой раскачки и защищает от глупых ошибок.

Так появился Go — язык, построенный на философии минимализма. Его главная особенность — основа почти не меняется, а команда профессиональных разработчиков постоянно его улучшает.

Почему вашему проекту нужен Go?

5 причин, почему бизнес в восторге от Go

1. Этот код экономит деньги

Сложный код дорого обходится. На его чтение, поддержку и онбординг новых разработчиков уходят недели и месяцы. Каждая новая фича превращается в квест по разгадыванию «что же имел в виду автор?».

Решение: простой синтаксис. В Go нет классов, наследования и прочих конструкций. Все лаконично и прозрачно. Новый разработчик открывает проект и через 2-3 рабочих дня уже понимает, что к чему.

Главная выгода для бизнеса: скорость. Быстрый онбординг команды, легкая поддержка, меньше багов из-за недопонимания. Время выхода на рынок сокращается, а стоимость владения проектом падает.

2. Производительность, которая конвертируется в клиентов. Оправдываем этот тезис на практике.

Один из наших клиентов столкнулся HR-задачей: в компании работает более 200 человек, и регулярно собирать обратную связь о настроении и пожеланиях сотрудников было сложно и неэффективно. Ручные опросы отнимали время и давали искаженную картину.

Мы разработали простого Telegram-бота для проведения автоматических опросов. Сотрудники в удобное время отвечают на короткие вопросы прямо в мессенджере.

Почему именно на Go?

Ценность бота — в регулярном и незаметном сборе данных. Он должен работать 24/7. Go, с его стабильностью и грамотным управлением ресурсами, гарантирует, что бот не «упадет» в самый ответственный момент и каждый сотрудник сможет пройти опрос.

Как это работает: представим, что опрос запускается одновременно для всех 200 сотрудников. Бот должен обработать десятки одновременных ответов без задержек. Встроенная в Go система конкурентности (горутины) идеально справляется с такими пиковыми нагрузками, обеспечивая плавный опыт для каждого пользователя.

Большая команда тут не нужна. Мы реализовали проект в течение 30 дней. Заказчик получил готовый продукт с минимальными инвестициями.

Результат для бизнеса:

1. Надежный инструмент, который в автоматическом режиме поставляет данные для принятия кадровых решений.

2. Руководство видит настроения в коллективе, во время реагирует на проблемы и, как итог, повышает уровень удержания ключевых специалистов.

3. Простой бот на Go стал эффективным звеном в HR-стратегии компании.

Лучший способ доказать эффективность инструмента — использовать его самому. Именно поэтому для нашего собственного B2B-продукта, платформы YouRich Бизнес, мы без колебаний выбрали Go.

Задача: Нам нужна была надежная и платформа для взаимодействия с клиентами, управления проектами и автоматизации внутренних процессов. Система, которую можно быстро развивать, добавляя новый функционал по запросу рынка и наших партнеров, не утопая в техническом долге.

Почему именно Go? Мы говорим не только о скорости работы, но и разработки. В бизнесе время — самый ценный ресурс. Способность быстро тестировать гипотезы и выкатывать новые фичи — это ключевое конкурентное преимущество.

  1. Лаконичный синтаксис GO Он позволяет нашей команде писать чистый, понятный код. Новых разработчиков мы внедряем в первые дни, а не недели. Тратим время на создание бизнес-логики, а не на борьбу со сложностью языка.
  2. Мгновенная обратная связь. Компиляция в Go занимает секунды. Разработчик вносит изменение и тут же видит результат. Этот короткий цикл «код → тест → результат» позволяет двигаться итерациям быстро и сохраняет команде мотивацию. Да, мы действительно «кайфуем» от этого процесса, потому что ничто так не вдохновляет, как быстрое превращение идей в работающий продукт.

Какая в этом бизнес-ценность?

  • Гибкость и быстрый выход на рынок. Мы можем оперативно реагировать на запросы наших клиентов. Нужна новая функция в личном кабинете? Мы можем спроектировать, разработать и внедрить ее быстрее, чем если бы использовали более громоздкий технологический стек.
  • Снижение стоимости владения. Меньше человеко-часов на каждую задачу — ниже стоимость разработки и поддержки. Это позволяет нам предлагать более выгодные условия для клиентов и инвестировать сэкономленные ресурсы в развитие продукта.
  • Наш стандарт: меньше багов. Для B2B-платформы стабильность — это не опция, а требование. Go обеспечивает предсказуемую производительность и надежность, поэтому мы уверены, что наш сервис для клиентов работает безупречно, пока мы сфокусированы на его развитии.

Выбрав Go для YouRich Business, мы сделали ставку на скорость, эффективность и надежность. Это позволяет нам не только создавать крутой продукт для наших клиентов, но и делать это с удовольствием и опережением рынка.

Пример работающего кода страницы для лидов нашей платформы YouRich Бизнес:

Код внизу⤵
package logic import ( "errors" "partners/internal/constants" "partners/internal/models" "partners/internal/repository" "partners/internal/tools" "time" ) type LeadLogicService struct { *BaseLogicService } func NewLeadLogicService(db repository.DatabaseManagerInterface) *LeadLogicService { return &LeadLogicService{ BaseLogicService: NewBaseLogicService(db), } } func (logic *LeadLogicService) Create(logger *tools.Logger, user models.User, reqParams models.LeadCreate) (bool, error) { var userId = user.Id var leadStatus = reqParams.LeadStatus if *user.UserRole == constants.UserRolePartner { userId = reqParams.UserId if _, err := logic.DB().User().GetByPartnerId(*user.UserPartnerId, reqParams.UserId); logger.Error(err, &user) != nil { return false, err } } if *user.UserRole == constants.UserRoleUser { leadStatus = constants.LeadStatusNew } var offerId = reqParams.OfferId if _, err := logic.DB().ReferralOffer().GetByPartnerId(*user.UserPartnerId, reqParams.OfferId); logger.Error(err, &user) != nil { return false, err } var dateCreate = time.Now() var modelCreate = models.Lead{ PartnerId: user.UserPartnerId, UserId: &userId, OfferId: &offerId, LeadStatus: &leadStatus, LeadSource: &reqParams.LeadSource, LeadSum: &reqParams.LeadSum, LeadFieldValues: &reqParams.LeadFieldValues, DateCreate: &dateCreate, DateUpdate: &dateCreate, } var modelPrepare = repository.PrepareModelAccess(repository.SqlOperationTagInsert, *user.UserRole, &modelCreate) if row, ok := modelPrepare.(*models.Lead); ok { if err := logic.DB().Lead().Create(*row); logger.Error(err, &user) != nil { return false, err } // Логируем создание лида event := "Добавлен лид" module := constants.UserModuleLead var logCreate = models.EventCreate{ PartnerId: user.UserPartnerId, UserId: &user.Id, Module: &module, EventId: &row.Id, Event: &event, } logic.CreateLog(logCreate) } return true, nil } func (logic *LeadLogicService) Update(logger *tools.Logger, user models.User, reqParams models.LeadUpdate, id uint) (bool, error) { var dateUpdate = time.Now() var modelUpdate = models.Lead{ Id: id, LeadStatus: reqParams.LeadStatus, LeadSource: reqParams.LeadSource, LeadSum: reqParams.LeadSum, LeadFieldValues: reqParams.LeadFieldValues, DateUpdate: &dateUpdate, } var modelPrepare = repository.PrepareModelAccess(repository.SqlOperationTagUpdate, *user.UserRole, &modelUpdate) if row, ok := modelPrepare.(*models.Lead); ok { if err := logic.DB().Lead().Update(*row); logger.Error(err, &user) != nil { return false, err } // Логируем обновление лида event := "Обновлен лид" module := constants.UserModuleLead var logCreate = models.EventCreate{ PartnerId: user.UserPartnerId, UserId: &user.Id, Module: &module, EventId: &row.Id, Event: &event, } logic.CreateLog(logCreate) } return true, nil } func (logic *LeadLogicService) Delete(logger *tools.Logger, user models.User, id uint) (bool, error) { if err := logic.DB().Lead().Delete(*user.UserPartnerId, id); logger.Error(err, &user) != nil { return false, err } // Логируем удаление лида event := "Удален лид" module := constants.UserModuleLead var logCreate = models.EventCreate{ PartnerId: user.UserPartnerId, UserId: &user.Id, Module: &module, EventId: &id, Event: &event, } logic.CreateLog(logCreate) return true, nil } type LeadGetResponse struct { Id uint `json:"id"` PartnerId uint `json:"partnerId"` DateCreate time.Time `json:"dateCreate"` DateUpdate time.Time `json:"dateUpdate"` models.LeadCreate `json:",inline"` } func (logic *LeadLogicService) Get(logger *tools.Logger, user models.User, id uint) (LeadGetResponse, error) { var res LeadGetResponse resSql, err := logic.DB().Lead().GetByPartnerId(*user.UserPartnerId, id) if logger.Error(err, &user) != nil { return res, err } resSql.JsonToStruct() var modelPrepare = repository.PrepareModelAccess(repository.SqlOperationTagSelect, *user.UserRole, &resSql) if row, ok := modelPrepare.(*models.Lead); ok { var leadFieldValues string if row.LeadFieldValues != nil { leadFieldValues = *row.LeadFieldValues } res = LeadGetResponse{ Id: row.Id, PartnerId: *user.UserPartnerId, DateCreate: *row.DateCreate, DateUpdate: *row.DateUpdate, LeadCreate: models.LeadCreate{ UserId: *row.UserId, OfferId: *row.OfferId, LeadStatus: *row.LeadStatus, LeadSource: *row.LeadSource, LeadSum: *row.LeadSum, LeadFieldValues: leadFieldValues, }, } } return res, nil } type LeadListResponse struct { List []LeadGetResponse `json:"list"` } func (logic *LeadLogicService) List(logger *tools.Logger, user models.User, filter models.LeadFilter) (LeadListResponse, error) { var res LeadListResponse var resList []LeadGetResponse resSql, err := logic.DB().Lead().List(filter) if logger.Error(err, &user) != nil { return res, err } for _, s := range resSql { s.JsonToStruct() var modelPrepare = repository.PrepareModelAccess(repository.SqlOperationTagSelect, *user.UserRole, &s) if row, ok := modelPrepare.(*models.Lead); ok { var leadFieldValues string if row.LeadFieldValues != nil { leadFieldValues = *row.LeadFieldValues } resList = append(resList, LeadGetResponse{ Id: row.Id, PartnerId: *user.UserPartnerId, DateCreate: *row.DateCreate, DateUpdate: *row.DateUpdate, LeadCreate: models.LeadCreate{ UserId: *row.UserId, OfferId: *row.OfferId, LeadStatus: *row.LeadStatus, LeadSource: *row.LeadSource, LeadSum: *row.LeadSum, LeadFieldValues: leadFieldValues, }, }) } } if resList == nil { resList = []LeadGetResponse{} } res = LeadListResponse{ List: resList, } return res, nil } func (logic *LeadLogicService) CreateEvent(logger *tools.Logger, user models.User, reqParams models.LeadEventCreate) (bool, error) { var offerId *uint = nil if reqParams.LeadUrl != "" && user.UserPartnerId != nil { offer, err := logic.DB().ReferralOffer().GetByPartnerIdAndUrl(*user.UserPartnerId, reqParams.LeadUrl) if err == nil { offerId = &offer.Id } } userData, _ := logic.DB().User().GetById(reqParams.UserId) var dateCreate = time.Now() var leadStatus = constants.LeadStatusNew var modelCreate = models.Lead{ PartnerId: userData.UserPartnerId, UserId: &userData.Id, OfferId: offerId, LeadStatus: &leadStatus, LeadPromocode: &reqParams.LeadPromocode, LeadLinkId: &reqParams.LeadLinkId, UserFingerprint: &reqParams.UserFingerprint, //UserIpAddress: &reqParams.UserIpAddress, DateCreate: &dateCreate, DateUpdate: &dateCreate, } var modelPrepare = repository.PrepareModelAccess(repository.SqlOperationTagInsert, *user.UserRole, &modelCreate) if row, ok := modelPrepare.(*models.Lead); ok { if err := logic.DB().Lead().Create(*row); logger.Error(err, &user) != nil { return false, err } } return true, nil } func (logic *LeadLogicService) CreateForm(logger *tools.Logger, user models.User, reqParams models.LeadFormCreate) (bool, error) { var userId uint var offerId uint var partnerId *uint // Сначала пытаемся найти по LeadLinkId if reqParams.LeadLinkId > 0 { offerData, err := logic.DB().ReferralOfferLink().GetById(reqParams.LeadLinkId) if err == nil { // Данные найдены по ссылке if offerData.UserId != nil { userId = *offerData.UserId } if offerData.OfferId != nil { offerId = *offerData.OfferId } if offerData.PartnerId != nil { partnerId = offerData.PartnerId } } } // Если данные не найдены по ссылке или ссылка не указана, ищем по промокоду if (reqParams.LeadLinkId == 0 || userId == 0 || offerId == 0) && reqParams.LeadPromocode != "" { offerData, err := logic.DB().ReferralOfferPromo().GetByPromoCode(offerId, reqParams.LeadPromocode) if err == nil { // Данные найдены по ссылке if offerData.UserId != nil { userId = *offerData.UserId } if offerData.OfferId != nil { offerId = *offerData.OfferId } if offerData.PartnerId != nil { partnerId = offerData.PartnerId } } } if offerId == 0 { offerId = reqParams.OfferId } // Проверяем, что мы нашли необходимые данные if offerId == 0 { return false, errors.New("2401: Offer not found") } var dateCreate = time.Now() var leadStatus = constants.LeadStatusNew var leadSource = constants.LeadSourceDirect var modelCreate = models.Lead{ PartnerId: partnerId, UserId: &userId, OfferId: &offerId, LeadStatus: &leadStatus, LeadSource: &leadSource, LeadPromocode: &reqParams.LeadPromocode, LeadLinkId: &reqParams.LeadLinkId, LeadFieldValues: &reqParams.LeadFieldValues, DateCreate: &dateCreate, DateUpdate: &dateCreate, } var modelPrepare = repository.PrepareModelAccess(repository.SqlOperationTagInsert, *user.UserRole, &modelCreate) if row, ok := modelPrepare.(*models.Lead); ok { if err := logic.DB().Lead().Create(*row); logger.Error(err, &user) != nil { return false, err } // Логируем создание лида из формы event := "Создан лид из формы" module := constants.UserModuleLead var logCreate = models.EventCreate{ PartnerId: user.UserPartnerId, UserId: &user.Id, Module: &module, EventId: &row.Id, Event: &event, } if err := logic.CreateLog(logCreate); err != nil { logger.Error(err, &user) } } return true, nil } type LeadInfoStatusListResponse struct { List []constants.LeadStatus `json:"list"` } func (logic *LeadLogicService) InfoStatusList() LeadInfoStatusListResponse { var res = LeadInfoStatusListResponse{ List: constants.LeadStatusList(), } return res } type LeadInfoSourceListResponse struct { List []constants.LeadSource `json:"list"` } func (logic *LeadLogicService) InfoSourceList() LeadInfoSourceListResponse { var res = LeadInfoSourceListResponse{ List: constants.LeadSourceList(), } return res }

3. Разработчики на GO работают, а не настраивают

В многих экосистемах половина времени уходит на подбор и настройку инструментов: для тестов, форматирования кода и сборки проекта. Это отвлекает и замедляет процесс.

В go богатая стандартная библиотека и встроенный инструментарий. Разработчик получает из коробки практически все, что нужно: утилиты для тестирования, анализа кода и создания документации. Не нужно ничего искать и дополнительно создавать. Разработка идет быстрее и предсказуемее. Команда сосредоточена на решении бизнес-задач, а не на борьбе с сложными конструкциями.

4. Устойчивость GO

Встроенный сборщик мусора и продуманная система горутины делают программы на Go чрезвычайно стабильными. Они грамотно распоряжаются памятью и вычислительными ресурсами, выдерживая высокие нагрузки без сбоев.

Наши клиенты спят спокойно, зная, что сервис не упадет от внезапного наплыва пользователей.

5. Не просто код, а живая экосистема

Выбрать малоизвестную технологию — это риск. А что если ее забросят? Где искать разработчиков? Кто ответит на вопросы?

За языком стоит Google и огромное, активное сообщество. Постоянно появляются новые библиотеки, фреймворки и инструменты. Найти ответ на любой вопрос — дело нескольких минут.

Go активно используется в таких гигантах, как Ozon, Avito, Tinkoff, Netflix и Uber. Это уже давно не нишевый язык, а мейнстрим для высоконагруженных систем.

Данные технологии будут развиваться и поддерживаться, а найти квалифицированных специалистов с каждым годом будет все проще.

Вывод: Go — не про моду, а математику

Выбор технологического стека — это не IT-вопрос, а стратегическое бизнес-решение. Можно посчитать: скорость разработки, стоимость поддержки, требования к инфраструктуре, надежность. С большой вероятностью в итоговом уравнении вы увидите два простых символа — G и O. Это язык для тех, кто ценит эффективность, надежность и предсказуемость. Для тех, кто строит бизнес на годы вперед.

Почему вашему проекту нужен Go?

Мы используем технологии:

Front-end: Next JS/React

Back-end: Golang (для новых проектов). PHP, если ваш проект уже написан на этом языке.

1
Начать дискуссию