İçeriğe atla

Uygulama

Besin veritabanı API sözleşmesi (deneysel)

Deneysel. FOOD_DB_API_URL değişkeninin lowcarbcheck.org dışındaki bir sunucuyu gösterebilmesi için besin veritabanının karşılaması gereken istekler ve yanıtlar

Bu sayfa, İngilizce belgeden makine çevirisiyle çevrildi.

Deneysel. Bu sayfa, uygulama sunucusunun bugün bir besin veritabanından neler istediğini açıklar. Kararlı bir API değildir. Bir ara sürüm bunu değiştirebilir ve değişiklik günlüğü bunu belirtir. Bunu uygulayan tek sunucu lowcarbcheck.org sunucusudur. Henüz açık kaynaklı bir sunucu yoktur ve bir uyumluluk testi bulunmaz. Bir tane geliştirirsen sözleşmenin ikinci bir kullanıcıyla gelişebilmesi için bize bir konuda haber ver.

openplate, besinleri ada göre kendi sunucusu üzerinden arar. Bu sunucu varsayılan olarak lowcarbcheck.org adresine sorar. FOOD_DB_API_URL, sunucuyu aynı istekleri yanıtlayan başka bir sunucuya yönlendirir. configuration.md, anahtarı ve kotayı açıklar. Bu sayfa ise istekleri ve yanıtları açıklar.

Sözleşmede neler var

Uygulama sunucusu dört tür istek yapar. Yalnızca ilki zorunludur.

İstekKullanım amacıSunucunda yoksa
POST /api/v1/foods/searchBesin arama ile yeni bir kaydın vitamin ve mineralleriBesin araması boş döner. Taramalar yapay zekanın kendi değerlerini korur.
GET /api/v1/foods/{slug}Eski günlük kayıtları için vitaminler (geriye dönük tamamlama)Eski kayıtlar vitaminsiz kalır.
GET /api/v1/nutrientsUygulamanın eksikleri gösterebilmesi için referans alımlarıUygulama bir günün neleri içerdiğini gösterir ve eksikleri göstermez.
GET /api/v1/nutrients/{slug}/foodsBesin maddesi ekranındaki "Bu besin maddesince zengin gıdalar"Liste boş kalır.

Uygulama sunucusu her hatayı boş bir yanıt olarak ele alır. Eksik bir uç nokta, zaman aşımı, 2xx dışı bir durum kodu veya uyuşmayan bir gövde, bir taramayı ya da günlük sayfasını asla durdurmaz. Buna hata durumunda açık kalma (fail-open) denir.

Her istek için kurallar

  • Temel adres, FOOD_DB_API_URL değeridir. Yukarıdaki yollar bunun sonuna eklenir.
  • Yalnızca JSON. İstekler accept: application/json gönderir. Yanıtlar UTF-8 JSON biçimindedir.
  • Anahtar. FOOD_DB_API_KEY ayarlandığında her istek authorization: Bearer <key> taşır. Anahtarın ne anlama geldiğine sunucun karar verir. Anahtar ayarlanmadığında üstbilgi bulunmaz.
  • İstek başına Zaman aşımı 4 saniyedir. Daha yavaş bir yanıt hata sayılır.
  • Bilinmeyen alanlar yok sayılır. Alanları serbestçe ekleyebilirsin. Eksik bir isteğe bağlı alan, "değer yok" olarak okunur.
  • 100 g başına. Tüm gıda değerleri 100 g gıda içindir. Enerji kcal cinsindendir. Makrolar gram cinsindendir.
  • null, 0 değildir. null, "bu kaynakta değer yok" anlamına gelir. 0, "ölçüldü ve sıfır" anlamına gelir. Uygulama yalnızca ölçülen değerleri hesaba katar, bu yüzden bilinmeyen bir değer için asla 0 gönderme.
  • Gizlilik. Arama isteği, bir ismin erişim günlüğüne düşmemesi için gıda adını adreste değil bir POST gövdesinde taşır. Bu özelliği koru: istek gövdelerini günlüğe kaydetme. Uygulama hiçbir hesap, günlük ve vücut verisi göndermez. Bkz. architecture.md.

POST /api/v1/foods/search

İstek gövdesi:

json
{ "q": "hähnchenbrust", "locale": "de", "limit": 10 }
  • q, kişinin yazdığı veya yapay zekanın tespit ettiği gıda adıdır.
  • locale; en, de, fr, it, es, tr değerlerinden biridir. Elinde bulunduğunda başlıkları bu dilde döndür.
  • limit bugün 10'dur.

Cevap:

json
{
  "results": [
    {
      "slug": "haehnchenbrust-roh",
      "locale": "de",
      "title": "Hähnchenbrust, roh",
      "canonicalName": "Chicken breast, raw",
      "url": null,
      "imageUrl": null,
      "macrosPer100g": {
        "kcal": 106, "protein": 23.1, "fat": 1.2,
        "carbs": 0, "fiber": 0, "sugars": 0, "polyols": 0
      },
      "netCarbsPer100g": 0,
      "attribution": "BLS 4.0, CC BY 4.0",
      "score": 0.92,
      "origin": "bls",
      "portionSize": null,
      "vitamins": { "vitaminA": 9, "vitaminC": 0, "vitaminB12": 0.3 },
      "minerals": { "sodium": 60, "potassium": 370 }
    }
  ]
}
AlanTürAnlamı
slugdize, zorunluGıda için sabit bir kimlik. Uygulama bunu saklar ve daha sonra ayrıntı isteğinde tekrar sorar.
localedize, zorunlutitle dili.
titledize, zorunluGösterilecek ad.
canonicalNamedize, zorunluSabit bir etiket olarak kullanılan İngilizce bir ad.
urldize veya nullGıdaya ait bir sayfa. Yoksa null. Bulunmaması null olarak okunur.
imageUrldize veya null, zorunluBir resim veya null.
macrosPer100gnesne, zorunlukcal, protein, fat, carbs, fiber, sugars, polyols. Her biri bir sayı veya null olur. Yedi anahtarın tümü bulunmalıdır.
netCarbsPer100gsayı veya null, zorunluLifsiz karbonhidrat. Bkz. Karbonhidrat.
attributiondize veya nullİçe aktarılan verilerin lisans atfı. Uygulama bunu gösterir.
scoresayı, zorunluAlaka düzeyi, 0 ile 1 arası. Bkz. Sıralama.
origindize veya nullBesinin nereden geldiği. Uygulamanın carbs alanını nasıl okuyacağını belirler. Bkz. Karbonhidrat.
portionSizesayı veya nullGram cinsinden tipik bir porsiyon.
vitaminsnesne veya nullBkz. Vitaminler ve mineraller. Besine ait hiç vitamin verisi olmadığında bu alanı atla.
mineralsnesne veya nullAynısı, mineraller için.

Karbonhidrat

İki kaynak karbonhidratları iki farklı şekilde gösterir ve uygulamanın bir besinin hangisini kullandığını bilmesi gerekir. origin alanı bunu belirtir:

originEsasmacrosPer100g.carbs ne anlama gelir
bls, curatedkullanılabilir (AB)Karbonhidratlar lif hariç. Lif ayrı bir satırdır.
fdc, user, proposaltoplam (ABD)Karbonhidratlar lif dahil. Net karbonhidrat, karbonhidrattan lifin çıkarılmasıyla bulunur.
yok veya başka herhangi bir değerbilinmiyorUygulama bunu toplam olarak değerlendirir ve kullanıcı elle değiştirebilir.

Verilerin AB biçimindeyse origin: "curated" gönder. ABD biçimindeyse origin: "fdc" gönder. Buradaki yanlış bir değer, temas ettiği her besinin karbonhidrat ve kalori değerlerini kaydırır, bu yüzden bildiğin bir besinle kontrol et.

netCarbsPer100g, 100 g başına senin belirlediğin net karbonhidrat değeridir ve uygulama buna kendi hesaplamasından daha çok güvenir. null, "bu besin için bilinmiyor" anlamına gelir. Uygulama bu durumda net karbonhidratı makrolardan ve yukarıdaki esastan hesaplar. Bilinmeyen bir değer için asla 0 gönderme.

Sıralama

results alanını en iyisi başta olacak şekilde alaka düzeyine göre sırala. Uygulama senin sıralamanı korur. Zayıf eşleşmeleri score değerine göre eler:

  • 0.4 veya üzeri bir score, gerçek bir metin eşleşmesi (tam, önek, sözcük veya alt dize) anlamına gelmelidir. Uygulama bunu 0.45'in altında eler.
  • 0.4'ün altındaki bir score, yalnızca yazım hatası eşleşmesi anlamına gelmelidir. Uygulama bunu 0.3'ün altında eler.
  • Yazım hatası eşleşmesi asla 0.4 veya üzerinde bir puan almamalıdır, aksi takdirde gerçek bir eşleşmenin önüne geçer.

Vitaminler ve mineraller

Her besin nesnesi isteğe bağlı iki blok taşır: vitamins ve minerals. Bir blok bu anahtarlara sahiptir ve uygulamanın okuduğu başka anahtar yoktur:

BlokAnahtarlarBirim
vitaminsbetaCarotene, vitaminA, vitaminD, vitaminB9, vitaminB12µg
vitaminsvitaminC, vitaminE, vitaminB1, vitaminB2, vitaminB6mg
mineralsnacl, potassium, sodium, calcium, magnesium, zinc, phosphorus, ironmg

Her değer bir sayı ya da null olur. Dışarıda bıraktığın bir anahtar null olarak okunur. Bloğun kendisi üç farklı duruma sahiptir ve bunlar aynı şey değildir:

  1. Blok yok (veya null): bu besinin hiçbir vitamin veya mineral verisi yok.
  2. Anahtar null: blok mevcut ve yalnızca bu değer bilinmiyor.
  3. Anahtar bir sayı: ölçülmüş bir değer. 0 gerçek veridir.

Uygulama, bir besin öğesini ancak ağırlıkça yeterli miktardaki besin ölçülmüş bir değer taşıdığında (bugün için yüzde 60) o gün karşılanmış sayar. Yanlış girilen sıfırlar, kişinin o vitaminden hiç almadığı gibi görünmesine neden olur, bu yüzden emin olmadığında null gönder.

Karotenoidleri zaten içeren A vitamini, retinol aktivite eşdeğeri (RAE) cinsindendir. betaCarotene bir bağlamdır, bir ekleme değildir. Kaynağın retinol eşdeğeri (RE) ya da uluslararası birim veriyorsa göndermeden önce dönüştür, aksi halde toplamlar yanlış olur.

Besin ayrıntısı

GET /api/v1/foods/{slug}?locale=de

Uygulama, kişinin vitamin özelliği çıkmadan önce kaydettiği bir besinin vitaminlerini ister. Eski bir arama sonucundan slug bilgisini gönderir.

  • Bulundu: durum 200 ve slug, vitamins ile minerals içeren bir besin nesnesi. Aramadaki blokların aynısı. Diğer alanlar yoksayılır.
  • O yerel ayarda bulunamadı: tam olarak şu gövdeyle durum 404: { "error": "not_found" }. Uygulama ardından diğer yerel ayarları dener (önce kişinin dili olmak üzere de, en, fr, it, es), böylece yalnızca tek bir yerel ayarda bilinen bir besin yine de bulunur. Başka herhangi bir 404 gövdesi "bulunamadı" olarak değil, başarısızlık olarak sayılır.
  • Bulundu ve blok yok: her iki blok da olmadan 200. Uygulama "kontrol edildi, veri yok" olarak kaydeder ve tekrar sormaz.

Her arama senin tarafında bir krediye mal olabilir, hiçbir yerel ayarın bilmediği bir slug için ise beşe kadar çıkabilir. Uygulama, cihaz başına farklı besin başına bir kez sorar.

Referans alımlar

GET /api/v1/nutrients

Aşağıdaki değerler yalnızca biçim içindir. Gerçek referans alımları değildir.

json
{
  "nutrients": [
    {
      "slug": "vitamin-c",
      "unit": "mg",
      "kind": "target",
      "rdaDe": {
        "source": "DGE 2024",
        "male":   { "14-18": 105, "19-30": 110, "31-50": 110, "51-70": 110, "over_70": 110 },
        "female": { "14-18": 90,  "19-30": 95,  "31-50": 95,  "51-70": 95,  "over_70": 95 },
        "pregnancy": 105,
        "lactation": 125
      },
      "rdaEu": null,
      "rdaUs": null
    }
  ]
}
  • slug aşağıdaki slug değerlerinden biri olmalıdır. Uygulama diğerlerini yoksayar.
  • kind, target ("yeterince aldın mı?") ya da ceiling ("altında kaldın mı?") değeridir. Bugün yalnızca sodyum bir ceiling değeridir. Bilinmeyen veya eksik bir değer target olarak okunur.
  • rdaDe, rdaEu ve rdaUs yayınlanmış üç ayrı belgedir: DGE, EFSA ve ABD (NASEM). Elinde olanları gönder, geri kalanı için null gönder. Uygulama, kurulum ayarıyla seçilen bir seferde tek bir dayanağı gösterir ve ikisini asla karıştırmaz.
  • Yaş aralıkları tam olarak 14-18, 19-30, 31-50, 51-70 ve over_70 şeklindedir. Her iki cinsiyet için de beşinin tümü gereklidir. Daha küçük bir yaş aralığı yoktur. Uygulama 14 yaş altındaki bir kişi için hiçbir referans göstermez.
  • pregnancy ve lactation isteğe bağlı sayılardır. Uygulama bunları yalnızca yerel olarak kullanır. Bir kişiyle ilgili hiçbir bilgi sana asla gönderilmez.

Besin öğesi slug değerleri:

Uygulama anahtarıKısaltma
vitaminAvitamin-a-retinol
vitaminCvitamin-c
vitaminDvitamin-d
vitaminEvitamin-e-tocopherole
vitaminB1vitamin-b-1-thiamine
vitaminB2vitamin-b-2-riboflavin
vitaminB6vitamin-b-6-pyridoxine
vitaminB9folic-acid-folate
vitaminB12vitamin-b-12-cobalamin
potassiumpotassium
sodiumsodium
calciumcalcium
magnesiummagnesium
zinczinc
phosphorusphosphorus
ironiron

A vitamininin bir parçası olduğu için betaCarotene değerinin kendine ait bir referansı yoktur.

Bir besin açısından zengin gıdalar

GET /api/v1/nutrients/{slug}/foods?locale=en&limit=8

json
{
  "nutrient": "vitamin-c",
  "unit": "mg",
  "foods": [
    { "slug": "acerola-raw", "title": "Acerola, raw", "url": null, "imageUrl": null,
      "netCarbsPer100g": 7.7, "attribution": null, "value": 1677.6 }
  ]
}

foods listesini en zenginden başlayarak sırala. value, 100 g başına düşen miktardır ve asla null olmaz. Değeri olmayan gıdaları 0 olarak göndermek yerine hiç ekleme.

Hatalar

DurumAnlamıUygulamanın yaptığı işlem
401Anahtar yanlış veya eksikinvalid_key kaydeder, bir bildirim gösterir, yapay zeka sayılarıyla çalışmaya devam eder
429Kota veya istek sınırı aşıldırate_limited kaydeder veya gövdede belirtildiğinde allowance_exhausted kaydeder
diğer her şeyBaşarısızlıkBildirim gösterilmeden "yanıt yok" kabul edilir

401 ve 429 için { "error": { "code": "allowance_exhausted" } } biçiminde bir gövde gönderebilirsin. Tanınan kodlar invalid_key, rate_limited ve allowance_exhausted kodlarıdır. Bilinmeyen bir kod, durum kodunun işaret ettiği nedene geri döner. Uygulama bir reddi asla önbelleğe almaz.

Sunucunu dene

Bunları sunucuna karşı çalıştır. Her biri yukarıdaki bölümlerle eşleşen JSON döndürmelidir.

bash
BASE=https://food.example.org
curl -s -X POST "$BASE/api/v1/foods/search" -H 'content-type: application/json' \
  -d '{"q":"apple","locale":"en","limit":3}'
curl -s "$BASE/api/v1/foods/apple-raw?locale=en"
curl -s "$BASE/api/v1/foods/does-not-exist?locale=en" -w '\n%{http_code}\n'   # 404, {"error":"not_found"}
curl -s "$BASE/api/v1/nutrients"

Ardından uygulama sunucusunda FOOD_DB_API_URL değerini ayarla, sunucuyu yeniden başlat ve uygulamada bir gıda ara. vitamins bloğuna sahip günlüğe kaydedilmiş bir gıda, günlüğündeki ilgili günün vitamin ve mineral kartında hesaba katılır. Katılmazsa, uygulama sunucusu günlüğünü oku: bir ret durumu, asla anahtarın kendisiyle değil, anahtarın ilk 16 karakteriyle birlikte uyarı düzeyinde günlüğe kaydedilir.

Kapsam dışındakiler

  • Hiçbir sunucu sağlanmaz. Kendin bir tane kurarsın ya da lowcarbcheck.org adresini kullanırsın.
  • Gıda önerileri (POST /api/v1/foods/proposals, FOOD_DB_BACKFILL) ayrı ve LowCarbCheck'e özgü bir özelliktir, bu sözleşmenin bir parçası değildir.
  • Henüz sürümleme yok. Yollar /v1 taşır, ancak bu sayfada "deneysel" yazdığı sürece biçim yine de değişebilir.
  • İletim şemaları kodun içindedir. Bugün için kural koyucu kaynak app/services/food-resolution/schema.ts (arama ve detay), app/lib/nutrient-reference.ts (referans alımlar ve zengin gıdalar) ve app/services/food-db/micronutrients-wire.ts (uygulamanın kendi geriye dönük doldurma rotası, bu sözleşmenin bir parçası değildir) kaynaklarıdır.

Bu sayfayı GitHub üzerinde düzenle