Услуга · разработка backend

Backend-разработка на Go: от архитектуры до продакшена

Берём серверную часть целиком или отдельный модуль внутри вашей команды. Решения принимает тот же человек, который их пишет, — поэтому схема архитектуры и код не расходятся.

  • Спринт от двух недель
  • Репозиторий ваш с первого дня
  • Удалённо по РФ

Опишите задачу

Вернёмся с вопросами по существу, границами работ и предложением по формату. Ответ в течение рабочего дня.

Стек

На чём пишем каждый день

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

  • Go 1.26
  • PostgreSQL 16
  • gRPC
  • Protobuf
  • buf
  • GraphQL
  • gqlgen
  • Kafka
  • Redis
  • Docker
  • GitLab CI
  • OpenTelemetry

Объём работ

Что входит в серверную часть

Backend — это не «написать эндпоинты», а доменная модель, контракты, схема данных, обмен с чужими системами и то, что видно дежурному в три часа ночи. Шесть слоёв, за которые мы отвечаем.

01

API и контракты

Контракт описывается первым: proto внутрь контура, GraphQL или OpenAPI наружу. Код клиента и сервера генерируется из него, а не дописывается руками.

  • buf: линтер и реестр proto
  • gqlgen: схема → типы Go
  • развитие без ломки клиентов
02

Доменный слой

Правила предметной области живут в пакете, который не знает ни про HTTP, ни про SQL: их можно проверить тестами без базы и без сети.

  • агрегаты и их инварианты
  • конечные автоматы статусов
  • тесты домена без инфраструктуры
03

Схема базы и миграции

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

  • ограничения на уровне БД
  • обратимые миграции на Goose
  • планы запросов на реальном объёме
04

Интеграции и обмен

Событие не теряется между коммитом в базу и публикацией: транзакционный Outbox, идемпотентные обработчики, повторы с нарастающей паузой.

  • Outbox → Kafka
  • идемпотентность по ключу
  • журнал обмена и алерты
05

Наблюдаемость и эксплуатация

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

  • OpenTelemetry: трейсы и метрики
  • health- и readiness-пробы
  • таймауты и дедлайны по умолчанию
06

Безопасность и доступ

Права проверяются на сервере при каждом вызове, секреты не живут в коде, а вход валидируется до попадания в домен — не «прикрутим в конце».

  • JWT, роли и права на сервере
  • секреты вне репозитория
  • валидация входа на границе

Инварианты

Как выглядит наш код

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

Агрегаты и конечные автоматы статусов

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

order.Confirm() → ErrInvalidTransition

Типизированные ошибки

Домен не знает ни про HTTP-коды, ни про gRPC-статусы: он возвращает собственные ошибки, которые вызывающий разбирает через errors.Is и errors.As. Перевод в код ответа происходит один раз, на границе транспорта, — поэтому «не найдено» не приезжает клиенту как 500, а сравнений текста ошибки по подстроке в коде нет.

errors.Is(err, ErrNotFound) → codes.NotFound

Зависимости через конструкторы

Никаких пакетных переменных, синглтонов и работы в init(): всё нужное приходит параметрами конструктора — репозиторий, часы, логгер, клиент соседнего сервиса. Список зависимостей виден в сигнатуре, а не выясняется на четвёртый час отладки; тест подставляет свою реализацию без библиотек подмены рантайма.

func NewOrderService(r Repo, c Clock) *Service

Границы модулей и запрет обхода слоёв

Модуль отдаёт наружу интерфейс и структуры данных, всё остальное закрыто в internal. Обращаться к чужой таблице напрямую, минуя владеющий ею модуль, нельзя — как и звать транспорт из домена. Правило проверяет линтер в CI, а не память ревьюера: так монолит остаётся модульным дольше первого квартала.

domain ← service ← transport

Обратимые миграции

У каждой миграции есть встречная: накат и откат прогоняются в пайплайне на пустой и на наполненной базе. Тяжёлые операции разводятся во времени — добавить и заполнить, переключить чтение, только затем удалить старое. Выкладка перестаёт требовать ночного окна.

goose up → goose down → goose up

Форматы

Три способа работать с нами

Один инженер уровня архитектора вместо команды из трёх джунов и менеджера-переводчика между вами и кодом. Меняется не состав, а то, как этот инженер встроен в вашу работу.

Спринт две недели

Когда задача очерчена и нужен закрытый результат в календарном окне.

2 неделификсированная стоимость

  • Состав работ и критерии готовности фиксируем до старта
  • Демо и передача в конце спринта, без переноса хвостов
  • Код в вашем репозитории с первого коммита
  • Понятный выход: спринт можно просто не продлевать
  • Не подходит задачам без границ и открытому исследованию
Обсудить спринт →
Чаще всего

Проект под техзадание

Когда нужна серверная часть целиком: от доменной модели до выкладки.

Под ТЗсмета после дискавери

  • Дискавери: домен, нагрузка, ограничения, внешние системы
  • Архитектура в модели C4 и решения в ADR до начала кода
  • Разбивка на этапы с отдельной приёмкой по каждому
  • Контракты, миграции, CI-гейты и документация внутри работы
  • Две недели на исправление ошибок реализации по ТЗ
Обсудить проект →

Архитектор part-time

Когда команда есть, но некому принимать решения и держать планку.

Part-timeзагрузка обсуждается

  • Ревью кода и разбор архитектурных развилок
  • Спорные решения оформляются в ADR письменно, а не в чате
  • Настройка CI-гейтов, границ модулей и правил контрактов
  • Разбор инцидентов, профилирование, работа с планами запросов
  • Не заменяет руки: задачи по-прежнему пишет ваша команда
Обсудить формат →

СтоимостьФикс. смета

Ни один из форматов не продаётся по прайсу: цена зависит от предметной области, состояния кода и числа внешних систем, которые придётся учитывать. Фиксированную стоимость считаем после короткого созвона — суммой, а не «вилкой от и до». Оплата по этапам.

Информация на сайте, включая описание форматов сотрудничества, не является публичной офертой. Итоговая стоимость, состав работ и сроки фиксируются в договоре с ИП Диденко М. С.

Кейсы

Где этот подход уже работает

Два продакшена на одном фундаменте: Go, gRPC внутри контура, генерируемые контракты и обратимые миграции. Разные предметные области — одинаковые правила.

Логистика · микросервисы

Логистическая платформа — восемь микросервисов за одним шлюзом

Автоматизация логистических операций: сервисы за централизованным API-шлюзом, вход через LDAP и JWT, логи через Vector в Elasticsearch.

16 ч → 9 минобработка ключевых процессов

Разбор проекта →

Учётная платформа · Go

ERP-платформа — модульный монолит на десять доменов

Единый контракт coreerp.v1 почти на два десятка сервисов, GraphQL-шлюз с DataLoader против N+1, транзакционный Outbox и Kafka, мультиарендность с шардированием.

100+обратимых миграций на Goose

Разбор проекта →

Качество

Что автоматически проверяет CI

Ревью человека ловит смысл, рутину должен ловить робот. Эти проверки стоят в пайплайне и делают сборку красной — их нельзя «согласовать словами» и пропустить перед релизом.

  • buf breakingИзменение proto сравнивается с веткой по умолчанию. Удалили поле, переиспользовали номер, поменяли тип — сборка падает раньше, чем сломается чужой клиент. Схему GraphQL проверяем так же.
  • codegenКод из proto и схемы GraphQL генерируется заново в пайплайне и сравнивается с закоммитованным. Расхождение означает, что сгенерированные файлы правили руками, — дальше это не проходит.
  • границыЛинтер знает карту модулей: домен не импортирует транспорт, чужие internal-пакеты недоступны, обход слоя не собирается. Архитектуру держит правило в конфиге, а не устная договорённость.
  • deadlinegRPC-вызов без контекста с дедлайном не проходит проверку. Иначе один зависший поход в соседний сервис выест пул горутин, и упадёт не он, а всё, что рядом.
  • raceТесты гоняются с детектором гонок на всех пакетах: гонка должна проявляться на сборке, а не в проде под пиковой нагрузкой в пятницу вечером.
  • покрытиеПорог покрытия на доменных пакетах — не ради цифры в отчёте. Он не даёт тихо добавить бизнес-правило, которое ни разу не выполнялось в тесте.

Этапы, оплата и гарантии подробно →

FAQ

Частые вопросы про backend

Не нашли ответ — напишите, разберёмся по вашей задаче.

Берёте проект целиком или подключаетесь к нашей команде?

И так, и так. Целиком — когда серверной части ещё нет: отвечаем за домен, контракты, базу и выкладку. Внутри команды — когда нужен сеньор на кусок: берём модуль и работаем в вашем репозитории по вашим правилам ревью.

Почему Go, а не Node.js или Python?

Go берём там, где важны предсказуемое поведение под нагрузкой, статическая типизация и простая эксплуатация: сервис собирается в один бинарник, конкурентность видна в коде. Там, где сильнее экосистема Python — обработка данных и ETL, — мы так и говорим и пишем на Python.

Предыдущий подрядчик сдал код, который никто не может развивать. С чего начать?

С чтения, а не с переписывания. Разбираем структуру модулей, миграции и точки интеграции и показываем, что можно спасти, а что дешевле сделать заново. Это отдельная работа с фиксированной ценой — аудит архитектуры. Только после него оценка сроков перестаёт быть выдуманной.

Кому принадлежит код и что остаётся после работы?

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

Как оценить работу, если техзадания ещё нет?

По короткому созвону обычно понятен класс задачи и её главные риски. Дальше — дискавери с фиксированной стоимостью: домен, нагрузка, ограничения и внешние системы превращаются в состав работ и смету. Решите не продолжать — материалы остаются у вас.

Контакты

Расскажите, что должен делать сервис — предложим архитектуру и формат

Разберём контекст, обозначим риски и границы, скажем, какой из трёх форматов подходит. Если задача не наша — скажем прямо. maincode — студия ИП Диденко М. С.

Смежные услуги

Если ваша задача другая

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