# api Пакет api реализует протокол, по которому общаются компоненты системы. Этот пакет не занимается передачей файлов и артефактов, соответствующие функции находятся в пакетах `filecache` и `artifact`. ## Worker <-> Coordinator - Worker и Coordinator общаются через один запрос `POST /heartbeat`. - Worker посылает `HeartbeatRequest` и получает в ответ `HeartbeatResponse`. - Запрос и ответ передаются в формате json. - Ошибка обработки heartbeat передаётся как текстовая строка. ## Client <-> Coordinator Client и Coordinator общаются через два вызова. - `POST /build` - стартует новый билд. * Client посылает в Body запроса json c описанием сборки. * Coordinator стримит в body ответа json сообщения, описывающие прогресс сборки. * _Тут можно было бы использовать websocket, но нас устраивает более простое решение._ * Чтобы послать клиенту неполный body, нужно использовать метод `Flush`. Прочитайте про [`http.ResponseController`](https://pkg.go.dev/net/http#ResponseController) и используйте его. * Первым сообщением в ответе Coordinator присылает `buildID`. - `POST /signal?build_id=12345` - посылает сигнал бегущему билду. * Запрос и ответ передаются в формате json. # Замечания - Конструкторы клиентов и хендлеров принимают первым параметром `*zap.Logger`. Запишите в лог события получения/отправки запроса и все ошибки. Это поможет вам отлаживать интеграционные тесты в следующей части задания. - Все методы должны "пробрасывать" контекст. * Контекст на клиенте нужно передать в функцию `http.NewRequestWithContext`. * Контекст на сервере нужно получить из `r.Context()` и передать в `Service`. - Код в этом пакете не должен запускать новые горутины. - Ошибку из `Service.StartBuild` нужно посылать клиенту. Если эта ошибка произошла после того, как хендлер начал писать body, то ошибку нужно передавать в потоке json-ов в поле `StatusUpdate.BuildFailed`. - Код всех вызовов в этом пакете работает одинаково: 1. Пользователь вызывает метод `*Client`. 2. Метод делает HTTP запрос к серверу. 3. `*Handler` принимает запрос, декодирует его и передает в `*Service`. 4. (*) В случае вызова `/build`, сервис пишет обновления в `StatusWriter`, а клиентский код читает эти обновления из `StatusReader`. 5. Ответ или ошибка из `*Service` возвращается пользователю.