Learning
What an API is (with and without Payload)
This page does nothing on the server except show you this lesson. No real data is loaded. The goal: understand what you would build by hand, and what Payload already gives you.
1. API in one sentence
An API is a way to ask for something and get an answerback. Like ordering at a restaurant: you don't cook in the kitchen — you place an order and wait for the food.
Ask (request)
"Find the link with code abc123"
Do the work
Server checks rules, looks in the database
Answer (response)
{ title: "Sale", url: "/pricing" }
2. The job we'll use as an example
Someone visits a tracked link like /r/abc123. The app needs to:
- Find the link whose short code is
abc123 - Save a click record
- Send the person to the real destination URL
Steps 1 and 2 are API work: asking the data layer for things.
3. Without Payload — you build the API yourself
You would write something like this by hand: a database table, a route that accepts requests, SQL (or an ORM query), error handling, and probably an admin form later. This is fake teaching code — not real code from this app.
A) Create a database table yourself
CREATE TABLE links (
id SERIAL PRIMARY KEY,
title TEXT NOT NULL,
short_code TEXT UNIQUE NOT NULL,
destination_url TEXT NOT NULL
);B) Write your own API route (example)
// GET /api/links/abc123
export async function GET(request) {
const code = "abc123"
// You talk to the database yourself
const link = await db.query(
"SELECT * FROM links WHERE short_code = $1",
[code]
)
if (!link) {
return Response.json({ error: "Not found" }, { status: 404 })
}
return Response.json(link)
}C) Save a click yourself
// POST /api/clicks
export async function POST(request) {
const body = await request.json()
await db.query(
"INSERT INTO clicks (link_id, clicked_at) VALUES ($1, NOW())",
[body.linkId]
)
return Response.json({ ok: true })
}D) Also build: login, permissions, admin screens…
// You would also need to invent:
// - user login + passwords
// - "only admins can create links"
// - a UI to create/edit links
// - validation (short code required, unique, etc.)
// - more routes for create / update / delete / listNone of that is wrong — it's just a lot of plumbing before your product features exist. Every new “thing” (Projects, Clicks, Users) means more tables + more routes + more forms.
4. With Payload — you describe the data, the API comes with it
In this project you define a collection (a type of thing), like Links. Payload then gives you:
- Database storage for that shape
- Ready-made ways to create / find / update / delete
- An admin UI at
/admin - Built-in users and access rules
A) You describe a Link once (simplified)
// collections/Links — "what is a Link?"
{
slug: "links",
fields: [
{ name: "title", type: "text", required: true },
{ name: "shortCode", type: "text", unique: true },
{ name: "destinationUrl", type: "text", required: true },
]
}B) Payload gives you an API you can call from your code
// Same job as the hand-built GET route — but much shorter
const result = await payload.find({
collection: "links",
where: {
shortCode: { equals: "abc123" },
},
})
const link = result.docs[0]C) Saving a click is also just asking Payload
await payload.create({
collection: "clicks",
data: {
link: link.id,
// other click fields...
},
})D) Or ask over HTTP (REST-style URL Payload provides)
// Payload also exposes URLs like:
// GET /api/links?where[shortCode][equals]=abc123
// POST /api/clicks
//
// Same idea as your hand-built routes — already wired up
// because you defined the Links and Clicks collections.5. Side by side
| Task | Without Payload | With Payload |
|---|---|---|
| Store links | Write SQL / migrations | Define fields on a collection |
| Find a link by code | Write a GET route + query | payload.find({ ... }) |
| Create a click | Write a POST route + insert | payload.create({ ... }) |
| Admin form to edit links | Build UI yourself | Comes with /admin |
| Who can create links? | Write auth checks yourself | access: { create: isAdmin } |
| Your product logic | You still write this | You still write this |
6. What Payload does not replace
Payload handles the boring data API layer. You still build the product parts, like:
- The redirect when someone hits
/r/[code] - Your dashboard screens
- CSV export, charts, special business rules
Think of Payload as the kitchen staff for data. Your app still decides the menu for users.
7. Tiny cheat sheet
API
A way to ask for something and get an answer
Request / response
The ask / the answer
Collection
A type of thing you store (Links, Projects, Clicks)
payload.find / create
Asking Payload: get me this / save this
Open this anytime at /learning. It never talks to the database.