- const aroma = searchParams?.get("aroma") ?? 8;
- const flavor = searchParams?.get("flavor") ?? 8;
- const acidity = searchParams?.get("acidity") ?? 8;
- const sweetness = searchParams?.get("sweetness") ?? 8;
+The above script installs an `get('/search')` HTTP endpoint that reads notes
+from the query parameters and looks up coffees in the database ordered by
+vector distance, i.e. how well they match.
- return await query(`
- SELECT
- Owner,
- Aroma,
- Flavor,
- Acidity,
- Sweetness,
- vector_distance_cos(
- embedding,
- '[${aroma}, ${flavor}, ${acidity}, ${sweetness}]'
- ) AS distance
- FROM
- coffee
- WHERE
- embedding IS NOT NULL AND distance < 0.2
- ORDER BY
- distance
- LIMIT 100`, []);
- }),
-);
-```
-
-This custom handler will let us query the coffees that most closely resemble
-our desired combination of notes, e.g.:
+This is a public API. While `trail` is up, we can simply test it by running:
```bash
$ curl "http://localhost:4000/search?aroma=8&flavor=8&acidity=8&sweetness=8"
@@ -152,134 +123,86 @@ $ curl "http://localhost:4000/search?aroma=8&flavor=8&acidity=8&sweetness=8"
]
```
-If we're only interested in the API, we're basically done. Otherwise, the
-following section will implement a simple React web App.
+We're done with the server side. This is already enough to build a simple UI.
+With a few simple commands we've ingested CSV data and built a custom HTTP
+endpoint using vector search.
+If you're not interested in a UI, the same approach setup could also be used to
+identify relevant documents for AI applications.
## A simple Web UI
-We recommend [vite](https://vite.dev/guide/) for setting up a simple SPA, e.g.:
+After setting up our database, vector search and APIs, we should probably use
+them for good measure. We could build a mobile app, have an LLM answer coffee
+prompts, or to keep it simple: build a small web UI.
+Moreover, a web UI also lets us touch more generally on bundling and deploying
+web applications with TrailBase.
+
+The specifics of the UI are not the focus of this tutorial that's why we
+chose React as the most well-known option and kept the implementation to less
+than 80 lines of code. In case you want to build your own, we recommend
+[vite](https://vite.dev/guide/) to quickly set up an SPA with your favorite JS
+framework, e.g.: `pnpm create vite@latest my-project -- --template react`.
+
+Our reference implementation, renders 4 numeric input fields to search for
+coffee with a given aroma, flavor, acidity and sweetness score:
+
+import uiCode from "../../../../../examples/coffeesearch/src/App.tsx?raw";
+
+
+
+We can run the UI in a vite dev-server by running:
```bash
-$ pnpm create vite@latest my-project -- --template react
+pnpm install && pnpm dev
```
-We can then swap out the template with `my-project/src/App.tsx`:
+## Deployment: Putting Everything Together
-```tsx
-import { useState, useEffect } from "react";
-import "./App.css";
-
-type Data = Array