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:

  1. Find the link whose short code is abc123
  2. Save a click record
  3. 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 / list

None 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

TaskWithout PayloadWith Payload
Store linksWrite SQL / migrationsDefine fields on a collection
Find a link by codeWrite a GET route + querypayload.find({ ... })
Create a clickWrite a POST route + insertpayload.create({ ... })
Admin form to edit linksBuild UI yourselfComes with /admin
Who can create links?Write auth checks yourselfaccess: { create: isAdmin }
Your product logicYou still write thisYou 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.