Skip to content

feat(tasks): обслуживать /tasks кодом — заработали skip, limit и отбор по пути - #17

Merged
fey merged 2 commits into
mainfrom
feat/tasks-real-implementation
Aug 14, 2026
Merged

feat(tasks): обслуживать /tasks кодом — заработали skip, limit и отбор по пути#17
fey merged 2 commits into
mainfrom
feat/tasks-real-implementation

Conversation

@fey

@fey fey commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Закрывает #16. Тикет: FEEDBACK-371.

Зачем

Статичный мок prism отдаёт пример из спецификации дословно, поэтому /tasks не применял skip и limit и на любой /tasks/{id} отвечал одной и той же задачей:

$ curl -s 'https://http.hexlet.app/http-api/tasks?skip=5&limit=10'   # то же, что без параметров
$ curl -s https://http.hexlet.app/http-api/tasks/2
{"id":1,"title":"Опубликовать курс по основам JavaScript",...}

Уроки приходилось подгонять под это: в 250-example оговаривать, что параметры не работают, а в 400-kinds прибивать сравнение REST и RPC к задаче 1.

Что стало

$ curl -s 'http://.../http-api/tasks?skip=1&limit=1'
{"tasks":[{"id":2,"title":"Записать скринкаст про HTTP API",...}],"total":3,"skip":1,"limit":1}

$ curl -s http://.../http-api/tasks/2
{"id":2,"title":"Записать скринкаст про HTTP API",...}

$ curl -s -o /dev/null -w '%{http_code}' http://.../http-api/tasks/999
404

/tasks обслуживает приложение. Операции вынесены в tasks-store.js, и его же использует JSON-RPC — два стиля делят логику, а не только текст задач, поэтому задача с одним номером в REST и в RPC одна и та же по построению.

Сохранено намеренно

Коды ответов. Раньше их давал prism из спецификации, и на них построены самостоятельные. Воспроизведены руками:

Запрос Код
GET /tasks 200
GET /tasks/1 200
GET /tasks/999 404
POST /tasks с {} 422
DELETE /tasks 405
DELETE /tasks/1 204

405 требует отдельных маршрутов на неподходящие методы: без них fastify отвечает 404 на существующий адрес с чужим методом.

Неизменяемость набора. POST и DELETE отвечают 201 и 204, но список не трогают. Сервер учебный, запросы идут одновременно от множества студентов, и мутации сделали бы уроки невоспроизводимыми. Проверяется тестом.

Маршрутизация

В Caddyfile два точных блока, /http-api/tasks и /http-api/tasks/*, а не tasks* — чтобы не перехватывать посторонние адреса. Проверено: /http-api/tasksfoo по-прежнему уходит к моку и отвечает 404. Префикс не срезается, поэтому приложение регистрирует полные пути.

Спецификация

Приведена к поведению: skip и limit объявлены uint16, как у остальных коллекций (были string), и добавлен 404 у get, update, delete. По спецификации читают документацию курса, расходиться с ответами ей нельзя. Проверено в контейнере: /http-api-openapi/json показывает 200, 404 и format=uint16.

Проверка

make test дополнен и вырос до 48 проверок: пагинация, отбор по пути, 404, 422 на отрицательном skip, неизменяемость набора после POST, плюс сверка примеров спецификации с набором данных — раньше совпадение выходило само, теперь ответы даёт код, а примеры остались документацией и могут разойтись молча.

Тест проверен на способность падать: если find перестаёт искать по id, падают 4 проверки и прогон выходит с кодом 1.

Сверх прогона собран образ и поднят контейнер, запросы шли через Caddy, как на проде. Соседние пути остались за моком (/users, /users/1, /posts, /posts/1, /comments, /login, /courses — все 200), остальные курсы не задеты (/http-protocol/example, /js-playwright/users, /postman/cookie, документация, главная — все отвечают).

Осталось за рамками

Остальные коллекции по-прежнему за статичным моком, поэтому у них skip/limit не работают, а /users/1/posts совпадает с /posts. Лечится тем же способом; в AGENTS.md это описано как то, что осталось.

После мержа и деплоя можно снять две скрытые пометки <!-- TODO --> в courses/ru/http_api_course и убрать оговорку про skip и limit из 250-example.

🤖 Generated with Claude Code

fey and others added 2 commits August 14, 2026 18:24
Статичный мок prism отдаёт пример из спецификации дословно, поэтому не применял
skip и limit, а на любой /tasks/{id} отвечал одной и той же задачей. Уроки
приходилось подгонять под это: в 250-example оговаривать, что параметры не
работают, а в 400-kinds прибивать сравнение REST и RPC к задаче 1.

Теперь /tasks обслуживает приложение. Операции вынесены в tasks-store.js, и его
же использует JSON-RPC, то есть два стиля делят не только текст задач, но и
логику: задача с одним номером в REST и в RPC одна и та же по построению.

Коды ответов, на которых стоят самостоятельные, воспроизведены руками, потому что
раньше их давал prism из спецификации: 200, 404 на несуществующую задачу, 422 на
негодное тело, 405 на неподходящий метод, 204 на удаление. 405 требует отдельных
маршрутов: без них fastify отвечает 404 на существующий адрес с чужим методом.

Набор данных остался неизменяемым. POST и DELETE отвечают 201 и 204, но список не
трогают: сервер учебный, запросы идут одновременно от множества студентов, и
мутации сделали бы уроки невоспроизводимыми.

В Caddyfile маршруты заданы точно, /http-api/tasks и /http-api/tasks/*, без
tasks*, чтобы не перехватывать посторонние адреса. Префикс не срезается, поэтому
приложение регистрирует полные пути.

Спецификация приведена к поведению: skip и limit объявлены uint16, как у
остальных коллекций, и добавлен 404 у get, update и delete. По спецификации
читают документацию курса, расходиться с ответами ей нельзя.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Прогон дополнен тем, что раньше было сломано и не проверялось: skip и limit
применяются, /tasks/{id} отдаёт именно эту задачу, несуществующая отвечает 404,
отрицательный skip отвечает 422, а после POST набор задач остаётся прежним.

Пути /tasks в прогоне переехали с порта мока на порт приложения, вместе с
префиксом: Caddy срезает его перед prism и оставляет перед приложением.

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

AGENTS.md обновлён под новое устройство: таблица кодов разведена по источникам
(prism против нашего кода), раздел про ограничение переписан на то, что осталось
у остальных коллекций, и описана неизменяемость набора.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@fey
fey merged commit 2ad58a5 into main Aug 14, 2026
2 checks passed
@fey
fey deleted the feat/tasks-real-implementation branch August 14, 2026 13:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant