Ask the Met in Querated.

Let's hunt for some art in the Met's gorgeous catalogue.

01

Search

Suggested searches
02

Filter

Negative years are BCE, so -500 means 500 BCE.

Works per page first
03

Choose fields

Artwork
Artist
Results
04

The query

POST /api/graphqlapplication/json
query SearchArtworks($search: String, $first: Int) {  artworks(search: $search, first: $first) {    total    items {      id      title      date      medium      tags      image(size: SMALL)      url      artist {        name        nationality        born        died      }    }    pageInfo {      startCursor      hasNextPage      endCursor    }    diagnosis {      searchAlone      filters {        arguments        matchesAlone        matchesWithout      }    }  }}

Variables

{  "search": "sunflowers",  "first": 12}

One request, one endpoint. Ctrl + Enter sends.

Decisions, not defaults

What Querated runs on

FrameworkNext.js
The page and the API ship as one app. The studio is rendered on the server, and the GraphQL endpoint is a route handler beside it, so there is one deploy and one origin.ADR 0001
APIGraphQL Yoga
One endpoint, and a response that carries only the fields the query asks for. The schema's descriptions are its documentation, and every query the studio can build is validated against it in tests.ADR 0001
Data loadingDataLoader
Twelve works by the same artist cost one artist search, not twelve. A loader per request removes repeated calls, and a shared cache answers repeat visits without calling the Met at all.ADR 0004
SecurityGraphQL Armor
Depth, alias, token and cost limits refuse an expensive query before it runs, so a single request can never fan out into thousands of Met calls. A nonce-based Content Security Policy guards the page.ADR 0005
MotionGSAP
Flies each token of the query along a curved path into the gallery, then builds the cards in. Everything is skipped when the visitor prefers reduced motion.ADR 0007
3DThree.js
Draws the particle beam that crosses the divider on send. It loads only after the page is idle, in its own chunk, so it never delays the first paint.ADR 0007
StylingTailwind CSS
The styling framework I build with. Its theme holds the two palettes, ink for the studio and wall for the gallery, and the syntax colours shared by the query and the cards.
HostingVercel
Builds Next.js natively, so production runs exactly what the build produced. Every pull request gets its own preview, and no deploy token lives in GitHub.ADR 0008
LanguageTypeScript
Everything here is written in TypeScript, from the Met's untrusted records through the resolvers to the cards, so a change to a shape fails the build rather than the page.
Quality gatesAutomated checks
Every pull request runs CI before it can merge: type checks, lint, tests, a production build, a Lighthouse audit, and a budget that fails the build if the initial JavaScript grows past 210 KB.ADR 0002
Back to my site.