API
У книги два интерфейса поверх одной модели: REST и GraphQL. Описание ниже собрано из тех же коллекций, из которых построен сам API, и обновляется вместе с ними — расходиться им негде. Машинное описание лежит по адресу /api-docs/openapi.json в формате OpenAPI 3.1: его принимают Postman, Insomnia и генераторы клиентов.
Как войти
POST /api/users/login с почтой и паролем возвращает токен. Дальше его передают заголовком:
Authorization: JWT <токен>
Браузеру проще: та же ручка ставит cookie, и дальше он ходит с ней сам.
Почему ответы разные
Одна и та же ручка отдаёт разное разным: хозяйство видит свои записи и публичные, Ассоциация — все, аноним — только публичные. Это правила доступа, а не схема ответа, и в описании их не выразить.
Пустая выдача чаще означает «вам это не видно», чем «этого нет».
Отбор
Условия передаются вложенными параметрами:
?where[state][equals]=alive &where[birthDate][greater_than]=2020-01-01
Стандартными средствами OpenAPI этот язык не описывается — в спецификации он объявлен строкой, чтобы не выглядеть точнее, чем есть.
С чего начать
Три задачи, с которыми к нам приходят чаще всего. Дальше справочник: в нём девяносто ручек, и он отвечает тому, кто уже знает, что ищет.
1. Войти и получить токен
С него начинается всё остальное: без токена ручки отдают только публичное.
BASE=https://…
curl -X POST \
"$BASE/api/users/login" \
-H content-type:application/json \
-d '{"email":"…","password":"…"}'В BASE — адрес этой системы. В ответе поле token, срок жизни — в поле exp.
2. Выгрузить своё стадо
Владельца в условии называть не нужно: выдача и так ограничена вашим хозяйством — правилами доступа, а не параметром запроса.
curl "$BASE/api/animals\ ?where[archived][not_equals]=true\ &limit=200&depth=0" \ -H "Authorization: JWT $TOKEN"
depth=0 отдаёт связи идентификаторами — быстрее и предсказуемее, если сами связанные записи не нужны.
3. Записать контрольную дойку
То, ради чего API чаще всего и подключают: дойки приходят каждый месяц и тысячами строк.
curl "$BASE/api/milk-tests" \
-H "Authorization: JWT $TOKEN" \
-H content-type:application/json \
-d '{"animal":123,
"date":"2026-08-01",
"milkYield":28.4}'Записать можно только животное своего хозяйства — это проверяется на сервере, а не в форме.
В примерах два подставляемых значения: $BASE — адрес, по которому открыта эта страница, и $TOKEN — то, что вернул вход. В справочнике ниже подставлять не нужно ничего: адрес там уже наш, а токен вводится один раз кнопкой авторизации.
Загружаем справочник…
Рядом с REST работает GraphQL — /api/graphql-playground. Это та же модель и те же правила доступа, другой способ спрашивать: за один запрос можно взять животное вместе с отёлами и родословной, не собирая его из трёх обращений.