Cosmica.
An editorial reader for NASA's Astronomy Picture of the Day, with the full archive since 1995 and a frontend that stays up when NASA's API doesn't.
- ROLE
- Full-Stack Engineer: design, frontend, API, infra
- TEAM
- Solo
- DATE
- Aug 2026 to Sep 2026
- TRACK
- Full-Stack
- STACK
- Next.js, React, TypeScript, TanStack Query, Zod, Upstash Redis, Tailwind CSS, Vitest

FIG. 03B ARCHITECTURE
- Next.js + TanStack Query, frontend. Connects to /api/apod + SSR pages (HTTPS).
- /api/apod + SSR pages, backend. Connects to Upstash Redis (RATE LIMIT), NASA client · Zod (FETCH). See note 1.
- Upstash Redis, storage. See note 2.
- NASA client · Zod, backend. Connects to NASA APOD API (HTTPS). See note 3.
- NASA APOD API, external.
NOTES
Decision
The browser never talks to NASA. Every request goes through one API route and one server-only client, so validation, caching, error handling and the media host allowlist each live in one place.
Trade-off
I put the rate limit (30 requests per minute per IP) in shared Redis instead of in memory, so it holds across serverless instances. The cost is an extra dependency and a network hop. When Redis isn't configured, the limiter lets traffic through rather than taking the site down.
What I got wrong
I trusted any response that passed the Zod schema and cached past dates for a year. When NASA moved APOD, its old API kept returning schema-valid placeholder pages, and I was serving and caching them. Now placeholder responses count as upstream errors and are never cached, and past dates are cached for a week at most.
RESULTS
- ARCHIVE DATES BROWSABLE (1995 TO TODAY)
- 11,000+
- AUTOMATED TESTS, RUN IN CI ON EVERY PR
- 75
- DATES CHECKED AGAINST THE NEW API BEFORE SHIPPING THE SWITCH
- 46
PROJECT 04 / 08