Меня зовут Артём, я занимаюсь коммерческой разработкой с 2019 года. Последние несколько лет я активно использовал Spring Boot для создания backend-сервисов на Java и Kotlin.
Но в какой-то момент захотелось попробовать что-то новое. Не потому что Spring надоел, а просто чтобы выйти из зоны комфорта и узнать, как чувствует себя проект на другом языке. Я решил: возьму уже начатый pet-проект, перепишу его на Go — и посмотрю, как изменится подход, скорость разработки, ощущения.
Это не туториал «как перепрыгнуть с Kotlin на Go». Это — эксперимент. Расширение границ и проверка своих навыков в новых условиях. Я не пытался доказать, что Go лучше, а просто дал себе возможность попробовать и сравнить.
Фронт у проекта был примитивный, построенный на HTML и JS без фреймворков. Углубляться в TypeScript и вылизывать интерфейсы я не планировал. Я бэкендер, и красить кнопки — точно не цель этого проекта (пока). Главное — чтобы всё работало стабильно, быстро и надёжно.
Так что сделал ставку на знакомые технологии, а всю новизну решил оставить для Go и инфраструктуры.
Заодно добавил интересный вызов: интегрировать GPT-4 через OpenAI API, сделать стриминг в реальном времени через WebSocket и всё это завернуть в CI/CD, который будет деплоить проект без лишних кликов.
Проект я писал около четырёх месяцев, в свободное время — вечерами и по выходным. Местами было сложно, но оно того стоило. В итоге родился полноценный AI-чат с авторизацией, конфигурацией, живыми ответами и гибкой архитектурой.
Важно: дальше в статье будет много текста и деталей. Это не обзор, а скорее история — по шагам и с погружением. Я хотел, чтобы на этом pet-проекте можно было попробовать много технологий, но не в ущерб здравому смыслу. Здесь есть и CI/CD, и WebSocket, и JWT, и взаимодействие с AI. И всё это с упором на:
-
безопасность,
-
отказоустойчивость,
-
асинхронность,
-
простоту масштабирования,
-
и, конечно, низкую стоимость эксплуатации.
Статья ориентирована на разработчиков, которые разбираются по чуть-чуть во всём — в backend-е, frontend-е, инфраструктуре и логике систем.
Эта статья — мой первый опыт публикации технического рассказа. И вышла она после майских праздников — символично: ощущаю это как свою маленькую победу.
Вот какие разделы вас ждут и зачем они нужны:
Почему Go + Gin, а не привычный Spring Boot
Разбираю, что подтолкнуло к смене стека и почему именно Go. Пишу честно: без фанатизма и без попытки продать Go как серебряную пулю. Просто сравнение ощущений и опыта.
CI/CD и деплой без кликов: GitHub Actions, Swagger, Docker и Portainer
Автоматизация — одна из главных целей. Я хотел, чтобы после каждого коммита новая версия приложения автоматически попадала на сервер: без SSH, без ручных рестартов и копипасты. В этом разделе расскажу, как получилось выстроить простой и надёжный пайплайн, который сам собирает образ, загружает его на сервер, обновляет прод и при этом ещё и Swagger держит в актуальном состоянии.
Интеграция с GPT-4 и адаптация под пользователя
Сердце проекта — AI. Рассказываю, как устроен prompt, как работают стриминговые ответы, какие параметры можно настроить и как GPT стал частью бизнес-логики. Будет и про фильтрацию, и про планы на мультимодальность (изображения, код и т.д.).
Реальное время: WebSocket, события, непрочитанные
Почему WebSocket, как устроена отправка сообщений и обновление счётчиков. Распишу архитектуру соединений, примеры событий и логику, которая делает чат «живым». Без диких подробностей — просто, понятно и с практическими выводами.
Архитектура проекта: как не перегрузить pet-проект
Разбор слоёв проекта: что за что отвечает, почему отказался от репозиториев. Пишу про GORM, интерфейсы, зависимости и почему важно не усложнять то, что можно сделать просто.
Безопасность: HTTPS, WSS, JWT и защита на всех уровнях
Описываю подход к авторизации, валидации токенов и работе с WebSocket. Зачем HTTPS, почему не ws://, как обрабатываются ошибки, и где можно упасть (но не стоит). Планы на разграничение ролей — тоже здесь.
Трудности разработки: от горутин до фронта
Раздел про грабли. Всё, что не получилось с первого раза: гонки в map, баги с каналами, «висящие» горутины. Как помог GPT-4 не сойти с ума, и почему писать UI без фреймворков — отдельный квест.
Итоги: что получилось, что не успел, и куда двигаться дальше
Заключение. Рефлексия. Что работает, что предстоит сделать. Какие выводы я сделал за эти четыре месяца, и чем хочу вдохновить других разработчиков.
Всё построено по принципу: от кода — к системе, от «почему так?» — к «как это поддерживать?».
Надеюсь, что этот рассказ окажется полезным не только как набор решений, но и как честная история с реальными трудностями, идеями и подходами. Поехали!
Почему Go + Gin, а не Kotlin + Spring Boot?
Первый вопрос, который, скорее всего, возник у многих:
зачем вообще менять проверенный стек?
Я сам долгое время писал на Kotlin с Spring Boot — с его аннотациями, DI, магией и встроенной экосистемой. Это реально удобно. Особенно когда проект большой, а времени — мало.
Но со временем начали ощущаться минусы:
-
громоздкость проекта даже на старте;
-
высокое потребление ресурсов;
-
долгое время запуска;
-
сложность отладки скрытых процессов (особенно, если не ты их писал).
Хотелось чего-то более простого, явного и быстрого:
-
лаконичный синтаксис, где почти нет «магии»;
-
мгновенная компиляция в один бинарник;
-
эффективная работа с памятью;
-
встроенная конкурентность (горутины — любовь с первого взгляда).
Я давно хотел подтянуть Go, и вместо учебных задач решил пойти ва-банк — взять живой проект, полностью его переписать, и посмотреть, как изменится разработка. Это был и вызов, и способ быстро прокачать скилл в боевых условиях.
Плюс ко всему, Go просто приятно писать. Ты чувствуешь, что контролируешь происходящее: от старта приложения до каждой строчки бизнес-логики. Это оказалось неожиданно приятно после многослойного Spring-приложения.
CI/CD и эксплуатация: GitHub Actions, Docker Swarm и Portainer
Когда я переписывал проект на Go, одной из целей было — автоматизировать всё, что можно. Хотелось просто писать код, пушить — и чтобы всё остальное происходило без моего участия. Так появилась связка: GitHub Actions + Docker + Portainer.
Что делает CI/CD пайплайн
После каждого пуша в main запускается пайплайн в GitHub Actions, который проходит по нескольким этапам:
-
Генерация Swagger-документации (OpenAPI)
Использую библиотеку, которая пробегается по Go-контроллерам и моделям, генерируяswagger.yaml.
Документация всегда остаётся актуальной — теперь её не нужно обновлять вручную. -
Сборка Docker-образа
Благодаря Go, итоговый бинарник получается лёгким и не требует JVM.
Используюmulti-stage Dockerfile:
сначалаgolang, затем финальный слой наalpine. -
Доставка и обновление
Готовый.tar-архив отправляется черезscpна сервер,
загружается в локальный Docker Registry (localhost:5000),
а затем выполняетсяdocker service update— и сервис обновляется.
Почему Docker Swarm, а не Kubernetes?
Kubernetes — мощный инструмент, но для одного сервера — перебор.
Я выбрал Docker Swarm, потому что:
-
он встроен в Docker (не требует отдельной установки);
-
не нужно писать десятки YAML-файлов;
-
достаточно одной команды:
docker stack deploy.
Если в будущем понадобится Kubernetes — архитектура проекта к этому готова. Миграция будет безболезненной.
Portainer — визуальный контроль и автоматизация
Чтобы не прыгать по ssh и docker ps, я подключил Portainer — лёгкую и удобную веб-панель.
ai_chat (бэкенд и фронт в одном сервисе), PostgreSQL для хранения данных и NGINX как SSL-прокси через Let's Encrypt. С его помощью можно:
-
видеть, какие контейнеры запущены и как работают;
-
быстро перезапускать сервисы;
-
прокидывать переменные окружения без выхода в консоль;
-
смотреть логи, даже если под рукой только браузер.
Portainer отлично дополняет CI/CD-процесс и даёт контроль «одним глазом».
Мониторинг и планы на будущее
Пока я полагаюсь на логи (docker logs, Portainer UI) и статусы контейнеров
Но в планах:
-
подключить Prometheus + Grafana для метрик:
-
количество WebSocket-соединений;
-
время отклика от GPT;
-
загрузка CPU и памяти.
-
-
настроить Alertmanager — чтобы оповещения приходили автоматически (Telegram, Email и т.д.).
Что ещё хочется внедрить
-
нагрузочное тестирование;
-
CI-пайплайн для фронта и его сборка отдельно от бэка;
-
отдельные контейнеры для фоновых задач (модерация, чистка логов и др.);
-
ролевая модель доступа на уровне инфраструктуры.
Вывод
Pet-проекту не нужен Kubernetes — пока. Но если придёт время — я готов.
Проект уже контейнеризирован, CI работает, инфраструктура гибкая.
А пока связка GitHub Actions + Docker Swarm + Portainer даёт всё, что нужно:
-
быстрое развёртывание;
-
простое обновление;
-
уверенность, что всё под контролем.
Интеграция GPT-4: как устроен AI-чат
Когда базовая инфраструктура была готова, я приступил к самому интересному — внедрению AI.
ai-chat: выполнено 439 запросов к Chat Completions с общим объёмом 82.7K входных токенов. Модель GPT-4 от OpenAI уже тогда казалась чем-то волшебным. Возможность организовать чат, в котором ответы приходят от мощного языкового движка, — звучало как магия. И стало техническим вызовом: как всё это обернуть в потоковое, гибко настраиваемое решение?
Как всё работает внутри
Когда пользователь пишет сообщение, сервер формирует prompt, в который входит:
-
system message: описание правил — например, "Ты ассистент в этом приложении, не обсуждай запрещённые темы, отвечай развёрнуто, но сдержанно." -
user message: последнее сообщение пользователя. -
Дополнительный контекст: email, настройки, история сообщений.
Этот prompt уходит в OpenAI, а в ответ приходит результат — с учётом всех настроек.
Уже сейчас backend поддерживает передачу
temperature,depthи даже пользовательские подсказки к каждому чату — всё это настраивается из UI.
Потоковый режим и WebSocket
Сначала я пробовал обычные REST-запросы. Но быстро понял, что хочется "эффекта живого общения": чтобы бот печатал ответ в реальном времени, а не присылал всё одним куском.
Для этого я включил режим stream в OpenAI API: модель начинает слать ответ токенами, и можно сразу транслировать их на клиент.
На стороне Go-сервера для каждого подключения запускается горутина, которая читает поток и пересылает данные в WebSocket.
Фронт ловит эти фрагменты и выводит как "печатающийся" текст — результат выглядит живо и даже эмоционально. Такое общение цепляет.
Почему не REST?
REST — это хорошо для запросов с мгновенным результатом. Но для AI-ответов в реальном времени он не подходит:
-
нельзя "частями" возвращать текст;
-
frontend не может показать постепенное появление символов;
-
пользователь не понимает, работает ли бот или "завис".
С WebSocket всё иначе: соединение живое, и каждый токен от GPT немедленно уходит клиенту. И именно это делает чат "живым".
Настройки для гибкости
Пользователь может сам выбрать:
-
temperature — насколько креативным будет AI;
-
depth — сколько сообщений учитывать в истории;
-
дополнительный контекст — например, "ты общаешься с клиентом по вопросам доставки".
Скриншот показывает реализацию потоковой генерации ответа от GPT через OpenAI API в Go: формируется POST-запрос с флагом stream: true, авторизация идёт по API-ключу, а результат передаётся по чанкам в обработчик.
Это уже реализовано в настройках чата, и сохраняется в базе для каждого пользователя.
Фильтрация и адаптация
Иногда GPT может вернуть что-то вроде:
{ "chat_id": "123", "user_id": "456" }
Это технический ответ, который не имеет смысла для обычного пользователя.
Поэтому я реализовал адаптер, который:
-
фильтрует "пустые" JSON-ответы;
-
добавляет
system-сообщения вроде: "В чате участвует user@example.com", чтобы AI понимал контекст; -
проверяет стиль общения — например, избегает неприемлемых тем.
На скриншоте показан адаптер, подготавливающий сообщения для GPT: слева — логика фильтрации, добавления email и генерации prompt, справа — системные инструкции (system prompts), автоматически добавляемые в начало переписки. Такой подход помогает модели лучше ориентироваться в диалоге, персонализировать ответы и соблюдать правила поведения в чате.
Планы по AI: дальше — больше
Уже сейчас GPT-4 — ядро всей интеллектуальной логики приложения. Но хочется пойти дальше:
-
Подключить другие модели для задач: GPT-4o, Vision, Whisper (голос), парсинг изображений.
-
Обработка вложений: например, пользователь присылает фото, а модель анализирует его и формирует ответ.
-
Настроить бизнес-роли: консультант, продавец, помощник поддержки — чтобы ответы были не просто текстом, а соответствовали цели чата.
-
Добавить параметры вроде
max_tokens,stop_sequence, интеграцию с внешними источниками — например, чтобы бот "смотрел в интернет" при необходимости.
Работая над этим модулем, я понял главное: AI — это не "просто ответ", это диалог, который можно настраивать и развивать. И это, честно, затягивает.
Реальное время на WebSocket: события и непрочитанное
Когда появилась первая интеграция с AI, стало ясно: чтобы чат был по-настоящему живым, нужно уходить от классического подхода с REST-запросами.
Пользователь не должен ждать, пока кто-то нажмёт F5. Он должен сразу видеть новое сообщение, обновлённый счётчик, или приход уведомления.
Так в проекте появился WebSocket — и с ним, по сути, вторая жизнь приложения.
Почему именно WebSocket?
У REST есть альтернатива — long polling или SSE (Server-Sent Events), но у всех них есть ограничения:
-
REST — хорош для запроса и ответа, но не годится для "пуша" от сервера;
-
polling грузит сервер и не даёт мгновенности;
-
SSE работает в одну сторону (только сервер → клиент).
А WebSocket — это полноценное двустороннее соединение:
-
сервер может слать данные в любой момент;
-
клиент может слушать и отправлять одновременно;
-
всё это работает поверх одного TCP-соединения — эффективно и быстро.
Какие события мы отправляем?
Сервер в любой момент может прислать:
-
chat_message— новое сообщение в чате; -
notification— событие вроде "тебя добавили в друзья"; -
unread_count— обновление количества непрочитанных.
Каждое событие имеет свой формат, чтобы клиент понимал, как его обработать. Например, chat_message содержит ID чата, отправителя и текст.
Архитектура соединений внутри
Когда клиент подключается к WebSocket:
-
Он передаёт JWT (через query или заголовок).
-
Сервер валидирует токен.
-
Создаётся
Session: WebSocket + userId + список чатов. -
Sessionкладётся вmap[userId]Session.
С этой map работают горутины через каналы, чтобы не было гонок и проблем с конкурентностью.
Как работает рассылка
Допустим, пользователь отправляет сообщение в чат:
-
оно сохраняется в базу данных;
-
формируется событие
chat_message; -
сервер ищет всех участников чата;
-
у кого открыт WebSocket — тем сразу отправляется сообщение;
-
если пользователь офлайн — сообщение считается непрочитанным.
Подсчёт непрочитанных
У каждого пользователя:
-
в базе хранится количество непрочитанных сообщений;
-
в памяти есть актуальные данные для быстрого доступа;
-
в UI — отображается badge со счётчиком.
Когда пользователь открывает чат:
-
счётчик сбрасывается;
-
отправляется событие
unread_count, чтобы UI обновился.
Пример обработки в реальном времени
У каждого пользователя есть своя горутина и канал сообщений:
type Session struct {
conn *websocket.Conn
send chan Event
}
Сервер пишет события в канал, а воркер читает их и шлёт в WebSocket.
Так можно безопасно и быстро отправлять сообщения, не блокируя основную логику.
Что ещё работает через WebSocket
-
Ответы от GPT — прямо по мере генерации;
-
Уведомления — новые друзья, приглашения;
-
Ошибки — если что-то пошло не так, клиент узнаёт мгновенно;
-
Статусы — кто в онлайне, кто набирает текст (в планах).
ProcessStreamingResponse, отвечающей за обработку потоковых AI-ответов от OpenAI в реальном времени. Слева — структура проекта с модулями, а справа — код, который читает входящий поток построчно, парсит JSON-чанки и передаёт их в WebSocket-клиент. Этот механизм лежит в основе стриминга ответов от GPT-4, обеспечивая эффект «печатающегося» текста прямо в чате. В результате чат стал ощущаться живым. Нет задержек, нет пустых экранов, нет ощущения "ничего не происходит".
И всё это — на одном компактном соединении. Легко, быстро и эффективно.
А главное — архитектура уже сейчас позволяет масштабировать систему: новые события, новые типы соединений, разделение каналов по тематикам — всё можно добавить без боли.
Архитектура проекта: минимум слоёв, максимум простоты
Переписывая проект на Go, я не стал изобретать архитектуру с нуля. Вместо этого — взял лучшее из привычного мира Spring и адаптировал к философии Go.
Результат получился простым, но мощным — как раз то, что нужно для быстрого старта и лёгкого развития.
📁 Структура проекта
Я разбил код по директориям:
-
routes— настройка маршрутов и привязка к обработчикам; -
controllers— обработка запросов, валидация, вызов сервисов; -
services— бизнес-логика, работа с БД, GPT и т.д.; -
models— все структуры: модели БД, DTO и вспомогательные типы.
Такой подход делает проект понятным с первого взгляда.
Заходишь в services — и сразу видишь, где живёт основная логика. Всё читаемо и без лишней "магии".
Почему я отказался от репозиториев
В Java-мире я привык к схеме controller → service → repository. Но в Go она не всегда нужна.
Вот мои причины отказаться от repository:
-
GORM уже предоставляет удобные методы:
db.First,db.Where,db.Create— и так далее; -
Интерфейсы Go и так дают нужную гибкость для тестов;
-
Чем меньше абстракций — тем проще и быстрее писать код.
Если в будущем захочу подменить БД или вынести слой доступа — легко добавлю интерфейс и внедрю его. Но пока всё работает и без этого.
В итоге получился проект с минимальным количеством слоёв, но с максимальной ясностью.
Go помогает писать просто, и эта архитектура отражает именно такой подход: никаких фабрик, DI-контейнеров и обёрток без необходимости.
Код — как открытая книга. И это даёт огромное удовольствие от работы.
Безопасность: HTTPS, WSS, JWT и единый подход для API и WebSocket
Когда строишь даже pet-проект, особенно связанный с личными сообщениями и авторизацией, хочется быть уверенным: данные пользователей защищены. Поэтому я сразу закладывал продакшен-подход — без компромиссов.
HTTPS и WSS: шифруем всё
Чат обменивается чувствительной информацией:
-
AI-ответы могут содержать личные вопросы,
-
WebSocket передаёт сообщения в реальном времени,
-
Авторизация построена на токенах.
Всё это должно передаваться только в зашифрованном виде.
Поэтому:
-
Сервер работает через HTTPS,
-
WebSocket подключается только по WSS,
-
Сертификат TLS — от Let's Encrypt, с автопродлением через
certbot.
💡 Почему это важно?
Потому что большинство браузеров не разрешают незащищённые WebSocket-соединения, если страница загружена по HTTPS. А ещё — потому что безопасность по умолчанию экономит нервы.
JWT: единый способ авторизации
Для всех защищённых API — и REST, и WebSocket — я использую JWT.
Что внутри токена:
-
userId, -
exp(время жизни), -
(в будущем —
role).
Как это работает:
-
После логина клиент получает JWT.
-
Для REST-запросов он кладёт токен в заголовок
Authorization. -
Для WebSocket — передаёт в query-параметре или header.
Сервер на каждом шаге проверяет:
-
подпись токена,
-
срок действия,
-
и если всё ок — прокидывает
userIdв контекст.
Если токен просрочен или подделан — пользователь получает 401 Unauthorized и дальше не проходит.
Централизованная обработка ошибок
Для REST API — ошибки всегда возвращаются в виде JSON:
{
"code": "auth.invalidToken",
"message": "Token expired"
}
Для WebSocket — соединение закрывается, но перед этим клиент получает финальное сообщение:
{
"code": "webSocket.closed",
"message": "WebSocket для уведомлений закрыт, повторное подключение..."
}
Такой подход делает поведение приложения предсказуемым — и удобным для фронтенда.
Recovery и устойчивость
Чтобы не уронить сервер при панике (например, из-за nil-указателя), я подключил middleware Recovery. Также пишутся логи всех запросов и ошибок.
Это помогает быстрее находить баги и не бояться нестандартных ситуаций в продакшене.
Хеширование сообщений в базе
Кроме защиты канала передачи данных, я позаботился и о хранении. Все сообщения, которые отправляются через чат — и от пользователя, и от AI — сохраняются в базу в хешированном виде (через SHA-256).
Зачем это нужно:
-
Дополнительный уровень защиты — даже если кто-то получит доступ к БД, он не сможет прочитать переписку.
-
Соблюдение приватности — сообщения могут быть чувствительными, и даже на pet-проекте хочется спать спокойно.
-
Прозрачная архитектура — хранение текстов без явного содержания упрощает юридические и этические аспекты при дальнейшем развитии проекта.
Важно: хеширование применяется только к сохранённой копии в базе, а не к передаваемым сообщениям в реальном времени. Таким образом, можно реализовать аналитику, поиск и другие фичи, если потребуется — без ущерба безопасности.
content не хранит открытый текст — сообщения сохраняются в зашифрованном (или хешированном) виде. Это сделано для защиты личной переписки пользователей от утечек даже в случае доступа к базе данных. В будущем — роли и права
Сейчас все пользователи равны. Но JWT уже содержит поле role, и я планирую:
-
admin— доступ к модерации, -
support— аналитика и техподдержка, -
bot— автоответы и системные события.
Роли будут проверяться на уровне middleware, а значит, основную логику менять не придётся.
Вывод:
Безопасность — это не второстепенная задача, а фундамент всей системы. Я заложил продакшен-подход с самого начала: от HTTPS и WSS до JWT и централизованной обработки ошибок. А дополнительное хеширование сообщений в базе — это страховка от любых утечек. Теперь я точно знаю: пользовательские данные под защитой, а архитектура готова к масштабированию, ролям и новым требованиям.
Трудности разработки: горутины, фронтенд и помощь GPT
Go, WebSocket и OpenAI — это не только про новые технологии, но и про множество граблей, которые на них лежат. И про то, как с этими граблями можно танцевать — особенно если рядом есть GPT.
Горутины и конкурентность
Go отлично справляется с многопоточностью, но он не прощает невнимательности. Я столкнулся с классической ошибкой:
-
Хранил все активные WebSocket-соединения в
map[userId]session, -
Писал в неё из нескольких горутин,
-
Не поставил
mutex.
Итог — гонка данных, падения, баги.
Race Detector сразу подсветил проблему, и я добавил sync.Mutex вокруг доступа к карте. Таких мелочей было много: где-то забытый defer close(), где-то лишний канал, который блокировал всю систему.
GPT оказался здесь не просто полезным — он стал настоящим напарником:
-
Подсказывал, как правильно синхронизировать доступ,
-
Объяснял поведение горутин,
-
Помогал проектировать очереди и worker'ы.
Трудности с полнотекстовым поиском
Ещё один открытый вопрос — это реализация полнотекстового поиска по сообщениям. Поскольку содержимое сообщений хранится в базе в хешированном виде, обычный поиск по тексту невозможен.
Хочется дать пользователю возможность искать по истории, но:
-
Простой LIKE не сработает (контент не в открытом виде),
-
PostgreSQL Full Text Search тоже не применим к хешам,
-
Расшифровка сообщений на лету — небезопасна и затратна.
🔍 Пока у меня нет идеального решения. Возможно, нужно будет хранить отдельный индекс расшифрованных сообщений в защищённой таблице, использовать внешнюю систему (например, Elasticsearch) или проектировать поиск как отдельный сервис с доступом только по JWT и ролям.
Фронтенд — как отдельный квест
Я по натуре бэкендер. И когда пришло время сделать UI, начал с чистого JavaScript — без React, Vue и фреймворков.
notification.js, который подключается к WebSocket для получения уведомлений и отслеживает непрочитанные сообщения. Очень много логов для отладки.Хотелось:
-
отображать сообщения в реальном времени,
-
видеть, как AI «печатает» ответ,
-
корректно подсчитывать непрочитанное,
-
и просто... чтобы всё выглядело прилично.
Проблем хватало:
-
браузер не успевал отрисовывать символы, если GPT присылал их слишком быстро,
-
scroll вниз не срабатывал на всех браузерах одинаково,
-
токен терялся при перезагрузке страницы.
С нуля — значит по-новому
Нечто похожее на UI в проекте появилось только на этом этапе. Это дало свободу:
-
переписать HTML под API-first подход,
-
сделать WebSocket-логику централизованной,
-
перенести авторизацию и state-менеджмент на JS.
В какой-то момент приложение из скрипта превратилось в живой чат, с динамикой, всплывающими уведомлениями и ощущением настоящего мессенджера.
GPT — как тиммейт
Было чувство, что работаю в паре:
-
я описывал задачу,
-
GPT давал реализацию или подсказывал подход.
Он помогал не тратить часы на Stack Overflow, а сразу идти к сути.
Вывод:
Трудности были — но именно они помогли прокачаться.
Я стал лучше понимать не только Go и JS, но и архитектуру, DevOps, и сам процесс разработки. А GPT помогал пройти этот путь быстрее и увереннее.
Итоги и планы: что получилось и куда двигаться дальше
Этот проект оказался для меня не просто попыткой попробовать Go — это было настоящее приключение. Смена стека, интеграция с GPT-4, борьба с горутинами и JavaScript, настройка DevOps и CI/CD — всё это превратилось в цепочку вызовов, преодоление которых дало невероятное ощущение роста.
Что получилось:
-
Я собрал полноценный AI-чат с WebSocket и GPT-4;
-
Настроил CI/CD на GitHub Actions с автообновлением через Portainer;
-
Развернул прод через Docker Swarm без боли;
-
Реализовал стриминг сообщений и работу в реальном времени;
-
Погрузился в Go и его конкурентную модель;
-
Написал свою первую большую статью
Что дальше?
Проект только начинается. Вот что планирую делать:
-
Развивать авторизацию и роли — добавить разграничение доступа, например, для поддержки, аналитики или автоматизации;
-
Прокачать AI — дать пользователю больше настроек, выбор ассистента, возможность использовать другие модели;
-
Обновить фронт — сделать его адаптивным и дружелюбным для мобильных;
-
Запустить нагрузочное тестирование — чтобы понять пределы;
-
Добавить централизованное логирование и мониторинг;
-
Подключить внешние API — например:
-
API погоды, чтобы бот мог отвечать на бытовые вопросы;
-
YouTube или Spotify API — для рекомендаций и поиска контента;
-
OCR/анализ изображений (например, через Vision API) — чтобы распознавать текст или предметы на картинках;
-
сервисы по верификации пользователей (email, телефон);
-
или даже интеграция с CRM-системой — чтобы AI мог подсказывать по клиентским данным.
-
Немного личного
Эту статью я заканчиваю в майские праздники — когда вся страна празднует День Победы. И пусть это совсем другая история, но для меня эти дни стали символом победы над собой: над усталостью, над страхом перед незнакомым, над отсутствием времени и над собственными сомнениями.
Спасибо, что дочитали до конца
Если вы задумываетесь о переходе с Kotlin/Java на Go — возможно, мой опыт вдохновит вас на первый шаг.
Или хотя бы напомнит: любой pet-проект — это уже шаг вперёд.
GPT может быть настоящим помощником, если его правильно использовать.
Новые технологии — это не страшно. Это интересно. Буду рад вашим вопросам, комментариям и идеям.
Автор: nekoluchiy
