← Все проекты уровня 6
Уровень 6 · Первые веб-сервисыВариант A

API событий

CRUD-каталог событий с валидированием времени и стабильной пагинацией расписания.

Техническое задание

Модель данных и назначение

Реализуйте REST API событий на Go. Сервис хранит записи только в памяти процесса и не подключается к базе данных. Событие содержит id, title, startsAt и capacity; startsAt принимает момент времени в UTC в формате RFC 3339, capacity является целым числом больше нуля. Идентификаторы генерируются сервером, клиент не может назначить или изменить id. При запуске хранилище пустое; перезапуск процесса очищает его.

API, проверки и эксплуатация

POST /api/events создаёт событие и возвращает 201 с созданной записью. Обязательны непустой title после удаления крайних пробелов, длина title от 1 до 160 символов, корректный startsAt в UTC и capacity от 1 до 100000. Некорректный JSON или поля дают 400 с устойчивым кодом ошибки и полем, которое не прошло проверку. GET /api/events принимает limit и offset: limit по умолчанию 20, допустим от 1 до 100; offset по умолчанию 0 и не может быть отрицательным. Ответ содержит items, limit, offset и total. Список сортируется по startsAt по возрастанию, затем по id, чтобы порядок оставался детерминированным при одинаковом времени.

GET /api/events/{id} возвращает событие или 404. PUT /api/events/{id} полностью заменяет title, startsAt и capacity после тех же проверок, сохраняет id и отвечает 200; отсутствующая запись даёт 404. DELETE /api/events/{id} удаляет запись и отвечает 204, повторное удаление возвращает 404. Все маршруты имеют префикс /api, неподдерживаемый метод возвращает 405, неизвестный маршрут — 404. Для ошибок используется единый JSON-формат без внутренних подробностей. Ограничьте размер тела запроса, отклоняйте неизвестные JSON-поля и второй JSON-объект в одном теле. Сервер корректно завершает HTTP-обработку при отмене контекста и имеет конечные таймауты чтения, записи и заголовков. Параллельные запросы не должны повреждать записи или выдавать частично обновлённое состояние; конкурентный доступ к хранилищу защищается синхронизацией. Пустая страница при offset больше total возвращает пустой items и исходный total, а параметры limit и offset с неверным числовым форматом дают 400. Секретов и внешних провайдеров у сервиса нет; журнал содержит только полезные операционные события и не копирует пользовательские значения без необходимости.

Структура программы

Небольшой internal/httpapi содержит обработчики и DTO, internal/events — проверки и CRUD-правила, internal/eventmemory — потокобезопасное хранилище в памяти. main.go читает конфигурацию, связывает пакеты, запускает сервер и завершает его по сигналу; правила тестируются без HTTP.

Критерии готовности

Ожидаемый результат

Поставка

  • Запускаемое Go REST-приложение хранит события в памяти процесса и предоставляет маршруты создания, чтения, замены, удаления и списка.
  • README описывает поля, статусы ошибок, сортировку, пагинацию и запуск; офлайн-тесты работают через временный локальный HTTP-сервер.

Приёмка

  • Создание корректного события возвращает 201; GET по возвращённому id показывает те же title, startsAt и capacity.
  • Capacity=0, не-UTC время и неизвестное JSON-поле каждое дают 400 без новой записи.
  • Список стабильно сортирует совпадающие startsAt по id и возвращает верные items, total, limit и offset.
  • PUT сохраняет id, DELETE возвращает 204; неизвестный id возвращает 404, повторное удаление также даёт 404.
  • Параллельное чтение и изменение не повреждают ответы и не вызывают гонку памяти.
  • README показывает зависимости между HTTP, правилами событий и памятью; CRUD-правила имеют тесты без HTTP, транспорт проверяется отдельно.