Kalkulator żywieniowy — przebieg integracji¶
Wszystkie ścieżki poniżej są względne wobec /partner/v1/nutrition-calculators.
Uwierzytelnienie jak w pozostałych endpointach: x-client-id, x-api-key, x-user-id.
Zasada ogólna¶
Kalkulator działa na profilu żywieniowym zwierzaka — osobnym bycie, powiązanym
z profilem zwierzaka. Kolejne wywołania uzupełniają ten profil kawałek po kawałku,
a calculate na koniec wylicza dzienną rację na podstawie tego, co się w nim zebrało.
Każdy setter zwraca cały zaktualizowany profil, więc nie trzeba po nich dopytywać o stan.
Krok 0 — obowiązkowy¶
To nie jest zwykły odczyt: jeśli profil żywieniowy jeszcze nie istnieje, ten endpoint go zakłada. Wszystkie pozostałe wywołania wymagają istniejącego profilu.
Wywołanie settera przed założeniem profilu kończy się 404 z komunikatem
mówiącym wprost, czego brakuje i czym to naprawić.
Kroki 1–5 — uzupełnianie profilu¶
Kolejność jest dowolna, poniższa jest naturalna dla formularza.
| Krok | Endpoint | Body |
|---|---|---|
| 1 | POST /measurements/{petId}/puppy-status |
{ "isPuppy": true } |
| 2 | POST /measurements/{petId}/weight |
{ "weight": 4.2, "age": 6 } |
| 3 | POST /measurements/{petId}/activeness |
{ "activeness": "MEDIUM" } |
| 4 | POST /measurements/{petId}/feed-type |
{ "feedType": "MIXED" } |
| 5 | POST /measurements/{petId}/feed-noutrishments |
wartości odżywcze, patrz niżej |
| 5b | POST /measurements/{petId}/feed-proportions |
{ "wetFeedProportion": 40 } |
activeness:LOW|MEDIUM|HIGHfeedType:DRY|WET|MIXEDweight: kilogramy, zakres 0–100age: miesiące, zakres 0–12
Wiek ma znaczenie tylko dla młodych¶
age jest używane wyłącznie wtedy, gdy isPuppy: true — wtedy wyliczenie idzie
wzorem wzrostowym. Dla dorosłego zwierzaka pole jest ignorowane, więc w interfejsie
warto pokazywać je dopiero po zaznaczeniu, że to szczenię lub kocię.
Wartości odżywcze zależą od rodzaju karmy¶
feedTypew tym wywołaniu przyjmuje tylkoDRYalboWET— to osobne zestawy wartości, po jednym dla każdego rodzaju karmy.- Przy
DRYwystarczy zestaw dla suchej, przyWET— dla mokrej. - Przy
MIXEDtrzeba wysłać oba zestawy, dwoma wywołaniami. - Węglowodanów się nie podaje — są wyliczane jako
100 − suma pozostałych. Suma pięciu pól musi być większa od zera i mniejsza od 100, inaczej wywołanie zostanie odrzucone.
Proporcja tylko dla karmy mieszanej¶
feed-proportions ma znaczenie wyłącznie przy feedType: "MIXED". Przy DRY
i WET całe zapotrzebowanie pokrywa jeden rodzaj karmy i pole jest pomijane.
wetFeedProportion: 40 oznacza, że 40% dziennego zapotrzebowania energetycznego
ma pochodzić z karmy mokrej, a 60% z suchej.
Wartość 0 jest traktowana jak brak proporcji — jeśli zwierzak ma dostawać wyłącznie
suchą karmę, należy ustawić feedType: "DRY", a nie MIXED z zerem.
Krok opcjonalny — własne zapotrzebowanie¶
Nadpisuje wyliczone zapotrzebowanie energetyczne. Nie działa dla młodych zwierząt —
przy isPuppy: true z podanym wiekiem pierwszeństwo ma wzór wzrostowy.
Krok końcowy — wyliczenie¶
Odpowiedź:
{
"diet": {
"DER": 900,
"wet": { "energy": 360, "portion": 480 },
"dry": { "energy": 540, "portion": 150 }
}
}
DER— dzienne zapotrzebowanie energetyczne w kcalenergy— ile kcal ma pochodzić z danego rodzaju karmy; sumuje się doDERportion— dzienna porcja w gramach
Uwaga na interpretację: proporcja dotyczy energii, nie masy. Karma mokra ma znacznie niższą gęstość energetyczną (dużo wody), więc przy 40% energii z mokrej jej udział wagowy będzie wyraźnie wyższy. Gramatury nie będą w stosunku 40:60 i nie jest to błąd.
Pola wet i dry przyjmują null, gdy dany rodzaj karmy nie występuje — przy
feedType: "DRY" zawsze wet: null, przy WET odwrotnie.
Niekompletny profil nie kończy się błędem¶
calculate nie sprawdza, czy profil jest gotowy. Dla karmy mieszanej bez ustawionej
proporcji zwraca 200 z samym zapotrzebowaniem:
null w obu polach jest więc wieloznaczne: może znaczyć „ten rodzaj karmy nie
występuje" albo „profil nie został jeszcze uzupełniony". Z samej odpowiedzi nie da
się tego rozróżnić.
Gotowość profilu sprawdza się przed wywołaniem, na podstawie GET /measurements/{petId}:
feedType |
Profil jest kompletny, gdy |
|---|---|
DRY |
feedNourishments zawiera wpis DRY |
WET |
feedNourishments zawiera wpis WET |
MIXED |
są oba wpisy i ustawione wetFeedProportion |
Brak wartości odżywczych dla wybranego rodzaju karmy to jedyny przypadek, w którym
calculate zgłasza błąd — 422 "Missing nutrient values for the selected feed type".
Kody błędów w tym module¶
| Sytuacja | Odpowiedź |
|---|---|
Setter wywołany przed GET /measurements/{petId} |
404 "Nutrition profile does not exist - call GET /measurements/{petId} first" |
| Suma pięciu wartości odżywczych ≥ 100 | 400 "Incorrect noutrishments: the five values must add up to less than 100" |
calculate bez wartości odżywczych dla wybranego rodzaju karmy |
422 "Missing nutrient values for the selected feed type" |
| Zwierzak bez gatunku albo gatunku innego niż pies i kot | 422 "Selected pet should be either dog or cat" |
| Zwierzak nie należy do użytkownika | 403 |
Wartości activeness i feedType, zakres wagi |
400 |
Wszystkie to błędy żądania, nie awarie — ponawianie nic nie da. 422 oznacza tu
żądanie poprawne składniowo, ale niewykonalne przy obecnym stanie profilu.
Warunki da się sprawdzić przed wywołaniem: profil zakłada GET /measurements, sumę
składników liczy się lokalnie, a gotowość profilu opisuje tabela wyżej.
Najczęstsze przyczyny błędów¶
| Objaw | Przyczyna |
|---|---|
404 przy pierwszym setterze |
Nie wywołano GET /measurements/{petId} |
400 „Incorrect noutrishments" |
Suma pięciu pól równa 100 lub większa |
422 przy calculate |
Brak zestawu wartości odżywczych dla wybranego rodzaju karmy |
wet: null i dry: null mimo MIXED |
Nie ustawiono wetFeedProportion (lub ustawiono 0) — odpowiedź to 200, nie błąd |
Wynik ignoruje custom-der |
Zwierzak oznaczony jako młody i ma podany wiek |
Przykładowa pełna sekwencja (kot, karma mieszana)¶
GET /measurements/{petId}
POST /measurements/{petId}/puppy-status { "isPuppy": false }
POST /measurements/{petId}/weight { "weight": 4.2 }
POST /measurements/{petId}/activeness { "activeness": "MEDIUM" }
POST /measurements/{petId}/feed-type { "feedType": "MIXED" }
POST /measurements/{petId}/feed-noutrishments { ...wartości..., "feedType": "DRY" }
POST /measurements/{petId}/feed-noutrishments { ...wartości..., "feedType": "WET" }
POST /measurements/{petId}/feed-proportions { "wetFeedProportion": 40 }
POST /calculate/{petId}
Profil jest trwały — przy kolejnych wizytach w kalkulatorze wystarczy GET
/measurements/{petId}, żeby odczytać zapisane wartości, i zaktualizować tylko to,
co się zmieniło, a następnie ponownie wywołać calculate.