feat(api): public GET /restaurants/by-slug/{slug}
Prerequisite for the customer webapp module (aiolabs/webapp, branch feat/restaurant-bundle): the webapp's /r/:slug route needs to resolve a slug to a Restaurant payload without an admin key. crud.get_restaurant_by_slug already exists (used by the server- rendered CMS routes in views.py); just expose it as a public REST endpoint. Mirrors api_get_restaurant by id and is declared before the bare-id route so the static prefix wins FastAPI's path match. Verified live against seeded 'Big Jay's Bustaurant': GET /restaurant/api/v1/restaurants/by-slug/big-jays-bustaurant -> 200 with the Restaurant payload.
This commit is contained in:
parent
dd756ecfc3
commit
6dae57f3f4
3 changed files with 27 additions and 1 deletions
|
|
@ -15,6 +15,7 @@ the catalog.
|
||||||
| Method | Path | Notes |
|
| Method | Path | Notes |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `GET` | `/restaurants/{id}` | Restaurant profile |
|
| `GET` | `/restaurants/{id}` | Restaurant profile |
|
||||||
|
| `GET` | `/restaurants/by-slug/{slug}` | Restaurant profile by URL slug — used by webapps that route on `/r/:slug` and need to resolve to an `id` before any other lookup. 404 when no match |
|
||||||
| `GET` | `/restaurants/{id}/menu` | `{restaurant, tree, items}` — the canonical [[menu-tree|menu tree]] (hydrated children + items per node) plus a flat enriched items list with modifier groups + availability windows pre-joined |
|
| `GET` | `/restaurants/{id}/menu` | `{restaurant, tree, items}` — the canonical [[menu-tree|menu tree]] (hydrated children + items per node) plus a flat enriched items list with modifier groups + availability windows pre-joined |
|
||||||
| `GET` | `/menu_items/{id}` | Single item |
|
| `GET` | `/menu_items/{id}` | Single item |
|
||||||
| `GET` | `/menu_nodes/{id}` | Single node row |
|
| `GET` | `/menu_nodes/{id}` | Single node row |
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,17 @@ of restaurants, especially the multi-restaurant cart pattern.
|
||||||
A webapp can either talk to one restaurant directly or aggregate
|
A webapp can either talk to one restaurant directly or aggregate
|
||||||
many. There's no central directory inside this extension — grouping
|
many. There's no central directory inside this extension — grouping
|
||||||
("festival", "collective space", "food court") is **emergent** via
|
("festival", "collective space", "food court") is **emergent** via
|
||||||
NIP-51 list events curated by whoever runs the venue:
|
NIP-51 list events curated by whoever runs the venue.
|
||||||
|
|
||||||
|
For the **single-venue** case, a webapp that routes on a URL slug
|
||||||
|
(`/r/big-jays-bustaurant`) resolves the slug → restaurant via the
|
||||||
|
public `GET /restaurants/by-slug/{slug}` endpoint
|
||||||
|
([[api-reference]]) and proceeds with that one `id` for menu reads
|
||||||
|
and order placement. Slug is just a URL nicety — internally
|
||||||
|
everything continues to key on the restaurant `id`.
|
||||||
|
|
||||||
|
For the **aggregator** case (multiple restaurants in one cart), the
|
||||||
|
webapp consumes a curated NIP-51 list event:
|
||||||
|
|
||||||
```
|
```
|
||||||
{
|
{
|
||||||
|
|
|
||||||
15
views_api.py
15
views_api.py
|
|
@ -59,6 +59,7 @@ from .crud import (
|
||||||
get_print_job,
|
get_print_job,
|
||||||
get_print_jobs,
|
get_print_jobs,
|
||||||
get_restaurant,
|
get_restaurant,
|
||||||
|
get_restaurant_by_slug,
|
||||||
get_restaurants,
|
get_restaurants,
|
||||||
get_settings,
|
get_settings,
|
||||||
move_menu_node,
|
move_menu_node,
|
||||||
|
|
@ -248,6 +249,20 @@ async def api_list_restaurants(
|
||||||
return await get_restaurants(wallet_ids)
|
return await get_restaurants(wallet_ids)
|
||||||
|
|
||||||
|
|
||||||
|
@restaurant_api_router.get("/api/v1/restaurants/by-slug/{slug}")
|
||||||
|
async def api_get_restaurant_by_slug(slug: str) -> Restaurant:
|
||||||
|
"""Public — used by the customer webapp to resolve a URL slug
|
||||||
|
(e.g. /r/big-jays-bustaurant) to a restaurant. Mirrors
|
||||||
|
api_get_restaurant; declared *before* the bare-id route so the
|
||||||
|
static prefix wins the path match in FastAPI's router."""
|
||||||
|
restaurant = await get_restaurant_by_slug(slug)
|
||||||
|
if not restaurant:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=HTTPStatus.NOT_FOUND, detail="Restaurant not found."
|
||||||
|
)
|
||||||
|
return restaurant
|
||||||
|
|
||||||
|
|
||||||
@restaurant_api_router.get("/api/v1/restaurants/{restaurant_id}")
|
@restaurant_api_router.get("/api/v1/restaurants/{restaurant_id}")
|
||||||
async def api_get_restaurant(restaurant_id: str) -> Restaurant:
|
async def api_get_restaurant(restaurant_id: str) -> Restaurant:
|
||||||
"""Public — used by the webapp to fetch profile metadata."""
|
"""Public — used by the webapp to fetch profile metadata."""
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue