# Turun ruokalistat, rajapinta

Kaikki reitit ovat `GET` eivätkä vaadi avainta. Vastaukset ovat UTF-8.

Palvelin: `http://ruoka.luhte.de`

## Yhteiset asiat

| Parametri | Merkitys |
| --- | --- |
| `lang` | `fi` tai `en`. Vaikuttaa annosten nimiin ja viikonpäiviin. |
| `pretty` | `1` muotoilee JSONin luettavaksi. |

Jokaisessa vastauksessa on `Access-Control-Allow-Origin: *`, joten rajapintaa voi käyttää suoraan selaimesta.

JSON-vastaukset sisältävät kentät `generated` ja `lang` varsinaisen sisällön lisäksi.

## Rivin kentät

Reitit `/api/day`, `/api/search` ja `/api/menus.csv` palauttavat samanlaisia rivejä.

| Kenttä | Merkitys |
| --- | --- |
| `date` | päivä muodossa YYYY-MM-DD |
| `day` | viikonpäivän nimi valitulla kielellä |
| `hours` | lounasaika tai null |
| `restaurant` | ravintolan nimi |
| `slug` | ravintolan tunnus osoitteissa |
| `campus` | kampus tai ryhmä |
| `section` | linjasto, esim. LOUNAS |
| `price` | hinta sellaisena kuin syöte sen antaa |
| `dish` | annoksen nimi |
| `tags` | merkinnät taulukkona, esim. ["G","L","Veg"] |
| `allergens` | allergeenit tai null jos syöte ei niitä julkaise |

## Ruokalistat

### `/api/menus`

Koko viikko kaikilta ravintoloilta, jäsennettynä.

| Parametri | Merkitys | Oletus |
| --- | --- | --- |
| `lang` | fi tai en | `fi` |

```
curl "http://ruoka.luhte.de/api/menus?lang=fi"
```

Vastaus: { updated, lang, campusOrder, restaurants: [ { name, campus, url, lat, lon, cost, days: [ { key, day, label, hours, sections: [ { name, price, items: [ { name, tags, allergens } ] } ] } ] } ] }

### `/api/day`

Yksi päivä litteinä riveinä. Helpoin kun haluat vain tämän päivän ruoat.

| Parametri | Merkitys | Oletus |
| --- | --- | --- |
| `pvm` | YYYY-MM-DD | `tänään` |
| `merkki` | vain tämän merkinnän annokset, esim. Veg | `kaikki` |
| `ravintola` | rajaa yhteen ravintolaan nimellä tai slugilla | `kaikki` |
| `lang` | fi tai en | `fi` |

```
curl "http://ruoka.luhte.de/api/day?pvm=2026-10-06&merkki=Veg"
```

Vastaus: { date, heading, rows: [ rivi ] }

### `/api/restaurant/{slug}`

Yhden ravintolan koko viikko. Slugin saat reitistä /api/restaurants.

| Parametri | Merkitys | Oletus |
| --- | --- | --- |
| `lang` | fi tai en | `fi` |

```
curl "http://ruoka.luhte.de/api/restaurant/galilei"
```

Vastaus: { updated, restaurant }  tai 404 jos slugia ei ole

### `/api/menus.csv`

Samat rivit CSV-taulukkona. Avautuu suoraan taulukkolaskentaan.

| Parametri | Merkitys | Oletus |
| --- | --- | --- |
| `pvm` | rajaa päivään | `koko viikko` |
| `merkki` | rajaa merkintään | `kaikki` |
| `ravintola` | rajaa ravintolaan | `kaikki` |
| `lang` | fi tai en | `fi` |

```
curl "http://ruoka.luhte.de/api/menus.csv?merkki=Veg"
```

Vastaus: CSV, otsikkorivi: date,day,hours,restaurant,slug,campus,section,price,dish,tags,allergens

## Haku ja koonnit

### `/api/search`

Annoshaku viikon listoilta. Kaikkien sanojen on osuttava, ääkköset eivät haittaa.

| Parametri | Merkitys | Oletus |
| --- | --- | --- |
| `haku` | hakusanat välilyönnillä eroteltuna | ei mitään |
| `merkki` | rajaa merkintään | `kaikki` |
| `pvm` | rajaa päivään | `koko viikko` |
| `limit` | enintään näin monta riviä | `100` |
| `lang` | fi tai en | `fi` |

```
curl "http://ruoka.luhte.de/api/search?haku=lohi&merkki=G"
```

Vastaus: { query, count, rows: [ rivi ] }

### `/api/dishes`

Viikon eri annokset ja monessako ravintolassa kukin on.

| Parametri | Merkitys | Oletus |
| --- | --- | --- |
| `merkki` | rajaa merkintään | `kaikki` |
| `pvm` | rajaa päivään | `koko viikko` |
| `lang` | fi tai en | `fi` |

```
curl "http://ruoka.luhte.de/api/dishes?merkki=Veg"
```

Vastaus: { count, dishes: [ { dish, tags, count, restaurants } ] }

### `/api/tags`

Käytössä olevat merkinnät ja niiden esiintymismäärät.

| Parametri | Merkitys | Oletus |
| --- | --- | --- |
| `lang` | fi tai en | `fi` |

```
curl "http://ruoka.luhte.de/api/tags"
```

Vastaus: { tags: [ { tag, count } ] }

## Ravintolat, aukiolo ja sijainti

### `/api/restaurants`

Ravintolat, koordinaatit ja tunnisteet ilman ruokalistoja. Kevyt ja harvoin muuttuva.

| Parametri | Merkitys | Oletus |
| --- | --- | --- |
| `lang` | fi tai en | `fi` |

```
curl "http://ruoka.luhte.de/api/restaurants"
```

Vastaus: { updated, campusOrder, restaurants: [ { name, slug, campus, url, lat, lon, costNumber, days, stale, error } ] }

### `/api/open`

Mitkä ravintolat ovat auki annettuna kellonaikana, ja montako minuuttia sulkemiseen.

| Parametri | Merkitys | Oletus |
| --- | --- | --- |
| `klo` | HH:MM | `nyt` |
| `pvm` | YYYY-MM-DD | `tänään` |
| `lang` | fi tai en | `fi` |

```
curl "http://ruoka.luhte.de/api/open?klo=12:30"
```

Vastaus: { date, at, open: [...], closed: [...], unknown: [...] }  jokainen { name, slug, hours, opensAt, closesAt, open, minutesLeft }

### `/api/nearest`

Lähimmät ravintolat linnuntietä. Sodexon aukioloaikaa ei ole syötteessä, joten sen open on null.

| Parametri | Merkitys | Oletus |
| --- | --- | --- |
| `lat` | leveysaste, pakollinen | ei mitään |
| `lon` | pituusaste, pakollinen | ei mitään |
| `limit` | montako palautetaan | `5` |
| `auki` | 1 = vain nyt auki olevat | `0` |
| `pvm` | YYYY-MM-DD | `tänään` |

```
curl "http://ruoka.luhte.de/api/nearest?lat=60.4557&lon=22.2856&limit=3"
```

Vastaus: { from, date, restaurants: [ { name, slug, lat, lon, meters, hours, open } ] }

## Historia

### `/api/history`

Milloin ja missä annosta on ollut tarjolla. Kertyy sitä mukaa kun palvelin hakee listoja.

| Parametri | Merkitys | Oletus |
| --- | --- | --- |
| `haku` | hakusanat | ei mitään |
| `limit` | enintään näin monta osumaa | `50` |

```
curl "http://ruoka.luhte.de/api/history?haku=lohikeitto"
```

Vastaus: { query, count, hits: [ { date, restaurant, dish, tags } ] }

### `/api/stats`

Historian tilastot: yleisimmät annokset ja vegaanivaihtoehtojen osuus ravintoloittain.

```
curl "http://ruoka.luhte.de/api/stats"
```

Vastaus: { days, firstDay, lastDay, dishes, uniqueDishes, top: [...], restaurants: [...] }

## Syötteet ja teksti

### `/tanaan`

Päivän lista pelkkänä tekstinä. Sopii terminaaliin ja skripteihin.

| Parametri | Merkitys | Oletus |
| --- | --- | --- |
| `pvm` | YYYY-MM-DD | `tänään` |
| `merkki` | rajaa merkintään | `kaikki` |
| `ravintola` | rajaa ravintolaan | `kaikki` |
| `lang` | fi tai en | `fi` |

```
curl "http://ruoka.luhte.de/tanaan?merkki=Veg"
```

Vastaus: text/plain

### `/rss`

Viikon listat RSS-syötteenä, yksi kohta per päivä.

| Parametri | Merkitys | Oletus |
| --- | --- | --- |
| `merkki` | rajaa merkintään | `kaikki` |
| `ravintola` | rajaa ravintolaan | `kaikki` |
| `lang` | fi tai en | `fi` |

```
curl "http://ruoka.luhte.de/rss?merkki=Veg"
```

Vastaus: application/rss+xml

### `/ical`

Viikon listat kalenteritapahtumina. Aukioloaika tulee tapahtuman kestoksi jos se tiedetään.

| Parametri | Merkitys | Oletus |
| --- | --- | --- |
| `merkki` | rajaa merkintään | `kaikki` |
| `ravintola` | rajaa ravintolaan | `kaikki` |
| `lang` | fi tai en | `fi` |

```
curl "http://ruoka.luhte.de/ical?ravintola=galilei"
```

Vastaus: text/calendar

## Palvelin

### `/api`

Rajapintojen luettelo koneluettavassa muodossa.

```
curl "http://ruoka.luhte.de/api"
```

Vastaus: { description, common, endpoints, sources }

### `/docs`

Tämä dokumentaatio.

```
curl "http://ruoka.luhte.de/docs"
```

Vastaus: text/html

### `/docs.md`

Sama dokumentaatio Markdownina, esimerkiksi repoon tallennettavaksi.

```
curl "http://ruoka.luhte.de/docs.md"
```

Vastaus: text/markdown

### `/api/health`

Palvelimen tila: välimuistin ikä, onnistuneet ravintolat, seuraava taustapäivitys.

```
curl "http://ruoka.luhte.de/api/health"
```

Vastaus: { ok, uptimeSeconds, upstream, history, tiles, refreshAt, nextRefresh, languages }

### `/api/refresh`

Vanhentaa välimuistin. Seuraava lataus hakee tuoreet listat.

```
curl "http://ruoka.luhte.de/api/refresh"
```

Vastaus: text/plain

### `/tiles/{z}/{x}/{y}.png`

Karttalaatta, rajattu Turkuun ja välimuistitettu levylle.

```
curl "http://ruoka.luhte.de/tiles/13/4602/2358.png"
```

Vastaus: image/png, 404 rajauksen ulkopuolella

## Esimerkkejä

```bash
# Mikä on auki puoli yhdeltä
curl -s "http://ruoka.luhte.de/api/open?klo=12:30" | jq -r '.open[].name'

# Lähin auki oleva ravintola
curl -s "http://ruoka.luhte.de/api/nearest?lat=60.4557&lon=22.2856&auki=1&limit=1"

# Viikon vegaaniannokset taulukkona
curl -s "http://ruoka.luhte.de/api/menus.csv?merkki=Veg" > vegaani.csv

# Päivän lista terminaaliin
curl -s "http://ruoka.luhte.de/tanaan"
```

## Lähteet

Ruokalistat tulevat Unican ja Sodexon omista syötteistä. Merkinnät ovat ravintoloiden omia.
Raaka-aineet voivat vaihtua suunnitellusta, joten tarkista soveltuvuus aina ravintolassa.
