> Какую архитектуру и технологии использовать для реализации клиента чата с REST API? (Go)
Уровень: senior · Роль: backend · Язык: Go · Категория: Технические вопросы
Компании: Лига Цифровой Экономики
Стек: Go
> Пример ответа
Короткий ответ
Для Go-клиента чата с REST API оптимальна модульная архитектура: транспортный слой на net/http с context и таймаутами, слой доменных моделей, репозиторий для работы с API и сервисный слой для бизнес-логики. Технологии - стандартная библиотека net/http или resty для удобства, encoding/json для сериализации, context для отмены запросов. Для long polling или WebSocket - gorilla/websocket. Ключевое - разделение ответственности, обработка ошибок и идемпотентность.
Подробное объяснение
Архитектура клиента чата строится вокруг нескольких слоёв:
- Транспортный слой - инкапсулирует HTTP-взаимодействие: базовый URL, заголовки, аутентификацию, ретраи. В Go это либо
http.Clientс настроеннымTransport, либо обёртка надresty. - Слой моделей - структуры для запросов/ответов API:
Message,User,ChatRoom. Они не должны зависеть от транспорта. - Репозиторий - интерфейс с методами
SendMessage,GetMessages,CreateChat. Реализация использует транспорт и маппит JSON в модели. - Сервисный слой - оркестрация: валидация, кэширование, обработка пагинации, повторные попытки при сетевых ошибках.
- Слой приложения - управление жизненным циклом:
contextдля отмены, graceful shutdown, конфигурация.
Для чата критичны:
- Таймауты - отдельно на соединение, на чтение ответа, на весь запрос.
- Ретраи - с экспоненциальной задержкой и jitter, но только для идемпотентных методов (GET, PUT, DELETE).
- Пагинация - курсорная или offset-based, реализуется в репозитории.
- Long polling - если REST не поддерживает WebSocket, клиент должен уметь держать соединение с
http.Client.Timeoutбольше обычного.
Технологии: net/http достаточно для большинства задач; resty добавляет удобные ретраи, middleware, JSON-хелперы. Для WebSocket - gorilla/websocket. Для конфигурации - envconfig или viper.
На практике
Начинаем с определения интерфейсов, чтобы тестировать репозиторий с моками. Транспорт настраивается один раз в main и передаётся в конструктор. Все методы принимают context.Context первым аргументом - это позволяет отменять запросы при shutdown или пользовательском действии.
Обработка ошибок: различаем транспортные ошибки (network, timeout) и бизнес-ошибки (4xx/5xx). Для последних - структурированный тип APIError с кодом и телом ответа. Ретраи только для 5xx и сетевых ошибок, не для 4xx.
Для long polling: отдельный метод PollMessages(ctx, chatID, cursor) с увеличенным таймаутом, который возвращает (messages, nextCursor, error). Приложение вызывает его в цикле с обработкой context.Canceled.
Пример кода
GOtype ChatClient struct {repo *ChatRepository}type ChatRepository struct {client *http.ClientbaseURL stringtoken string}func (r *ChatRepository) SendMessage(ctx context.Context, msg *Message) error {body, _ := json.Marshal(msg)req, _ := http.NewRequestWithContext(ctx, http.MethodPost, r.baseURL+"/messages", bytes.NewReader(body))req.Header.Set("Authorization", "Bearer "+r.token)req.Header.Set("Content-Type", "application/json")resp, err := r.client.Do(req)if err != nil {return fmt.Errorf("send message: %w", err)}defer resp.Body.Close()if resp.StatusCode >= 400 {return &APIError{Code: resp.StatusCode, Message: "failed to send"}}return nil}func (r *ChatRepository) PollMessages(ctx context.Context, chatID string, cursor string) ([]Message, string, error) {url := fmt.Sprintf("%s/chats/%s/messages?cursor=%s", r.baseURL, chatID, cursor)req, _ := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)resp, err := r.client.Do(req)if err != nil {return nil, "", err}defer resp.Body.Close()var result struct {Messages []Message `json:"messages"`NextCursor string `json:"next_cursor"`}if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {return nil, "", err}return result.Messages, result.NextCursor, nil}
Как отвечать на собеседовании
Начни с верхнеуровневого разделения на слои, затем уточни, какие технологии выбираешь и почему. Подчеркни, что стандартная библиотека Go достаточна для 90% случаев, а сторонние библиотеки - только для удобства. Обязательно упомяни context и таймауты - это ключевой момент для клиентов. Расскажи про обработку ошибок и ретраи, покажи, что понимаешь разницу между идемпотентными и неидемпотентными запросами. Если спросят про long polling - объясни, как это влияет на настройку http.Client. Не углубляйся в детали реализации, пока не спросят.
Что проверяет интервьюер
- Понимание принципов построения клиентов API: таймауты, ретраи, обработка ошибок.
- Умение проектировать интерфейсы и разделять ответственность между слоями.
- Знание Go-специфики:
context,http.Client,json.Decoder. - Понимание trade-off между стандартной библиотекой и сторонними инструментами.
- Способность объяснить, как клиент будет работать в реальном чате: пагинация, long polling, отмена запросов.
Типичные ошибки
- Использование глобального
http.DefaultClientбез таймаутов - это приводит к зависаниям. - Игнорирование
context- клиент нельзя отменить, что критично для чата. - Ретраи для POST без идемпотентности - можно дублировать сообщения.
- Смешивание транспорта и бизнес-логики в одном слое - сложно тестировать.
- Необработка
io.EOFпри long polling - сервер может закрыть соединение, нужно переподключаться. - Отсутствие лимитов на размер ответа - злоумышленник может прислать гигантский JSON.
> Похожие задачи по Go
Как организовать мьютексы для многопоточной работы с данными по разным пользователям без блокировки всего стореджа
Какие алгоритмы балансировки существуют
Как описать схему базы данных для модели библиотеки с сущностями автор, книга, читатель и связями между ними
Какие сигналы существуют в операционной системе
> Похожие задачи по backend
Какие алгоритмы балансировки существуют
С какими типами данных чаще всего работали: списки, словари, массивы
Как описать схему базы данных для модели библиотеки с сущностями автор, книга, читатель и связями между ними
Какие сигналы существуют в операционной системе
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью