CoachnestCoachnest
Sign InGet Started
Back to course

Mastering CRUD: Build Full-Stack Database Applications

…
—
Contents
1

What Is CRUD and Why It Matters

Reading12mFree
2

CRUD, REST, and HTTP Verbs

Reading14mFree
3

The Data Lifecycle of a Record

Reading11m
4

Course Project Tour: TaskFlow

Video9m
5

Chapter 1 — Quiz

Quiz8m
6

Tables, Rows, Columns & Types

Reading14m
7

Primary Keys & IDs (Auto-increment vs UUID)

Reading13m
8

Relationships: One-to-Many & Many-to-Many

Reading16m
9

Normalization & Schema Design Principles

Reading14m
10

Modeling TaskFlow with Prisma

Reading13m
11

Chapter 2 — Quiz

Quiz8m
12

INSERT — Creating Rows

Reading13m
13

SELECT — Reading & Filtering

Reading16m
14

UPDATE — Changing Rows Safely

Reading12m
15

DELETE — Removing Rows

Reading11m
16

Live SQL: A Full CRUD Session

Video15m
17

Chapter 3 — Quiz

Quiz9m
18

REST API Design for CRUD Resources

Reading14m
19

HTTP Status Codes That Tell the Truth

Reading12m

Scaffolding the API (Express & Next.js)

Reading16m
21

Connecting an ORM (Prisma) to Your Routes

Reading13m
22

Chapter 4 — Quiz

Quiz8m
23

Building the Create Endpoint End-to-End

Reading15m
24

Reading a Single Resource

Reading11m
25

Listing Collections

Reading13m
26

Live Coding: Create & Read

Video16m
27

Chapter 5 — Quiz

Quiz8m
28

PUT vs PATCH: Full vs Partial Updates

Reading13m
29

Authorization: Who Can Change This Row?

Reading12m
30

Soft Delete, Hard Delete & Restore

Reading14m
31

Idempotency & Concurrency Control

Reading13m
32

Chapter 6 — Quiz

Quiz9m
33

Input Validation with Zod

Reading14m
34

Mass Assignment & Over-Posting

Reading11m
35

SQL Injection & Safe Queries

Reading13m
36

Consistent Error Handling

Reading12m
37

Chapter 7 — Quiz

Quiz9m
38

Offset vs Cursor Pagination

Reading15m
39

Filtering & Dynamic WHERE Clauses

Reading13m
40

Safe Sorting & Full-Text Search

Reading14m
41

Indexing for Fast Reads

Reading13m
42

Chapter 8 — Quiz

Quiz9m
43

Forms & Creating Records from the UI

Reading14m
44

Fetching & Displaying Data

Reading13m
45

Optimistic Updates & Deletes

Reading14m
46

Building the TaskFlow UI

Video17m
47

Chapter 9 — Quiz

Quiz8m
48

Transactions & Data Integrity

Reading15m
49

Testing Your CRUD Endpoints

Reading14m
50

Caching, N+1 & Performance

Reading13m
51

Deploying & Migrating Safely

Reading14m
52

Chapter 10 — Final Quiz

Quiz10m
←→navigate lessons
Chapter 4 of 10·Chapter 4 — Building a CRUD REST API
Lesson 20 of 52Reading16 min

Scaffolding the API (Express & Next.js)

Scaffolding the API¶

Let's stand up the routes. We'll show two popular stacks; the shape is identical.

Express¶

js
16 lines
1import express from "express";
2const app = express();
3app.use(express.json());
4
5// CREATE
6app.post("/api/v1/tasks", createTask);
7// READ (list)
8app.get("/api/v1/tasks", listTasks);
9// READ (one)
10app.get("/api/v1/tasks/:id", getTask);
11// UPDATE (partial)
12app.patch("/api/v1/tasks/:id", updateTask);
13// DELETE
14app.delete("/api/v1/tasks/:id", deleteTask);
15
16app.listen(3000);

A handler signature:

js
5 lines
1async function getTask(req, res) {
2  const task = await prisma.task.findUnique({ where: { id: req.params.id } });
3  if (!task) return res.status(404).json({ error: "Task not found" });
4  res.json({ data: task });
5}

Next.js App Router¶

The App Router maps files to routes. A route.ts exports functions named after HTTP verbs.

ts
14 lines
1// app/api/v1/tasks/route.ts
2import { NextRequest, NextResponse } from "next/server";
3import { prisma } from "@/lib/prisma";
4
5export async function GET() {
6  const tasks = await prisma.task.findMany();
7  return NextResponse.json({ data: tasks });
8}
9
10export async function POST(req: NextRequest) {
11  const body = await req.json();
12  const task = await prisma.task.create({ data: body });
13  return NextResponse.json({ data: task }, { status: 201 });
14}
ts
7 lines
1// app/api/v1/tasks/[id]/route.ts
2export async function GET(_req: NextRequest, { params }: { params: Promise<{ id: string }> }) {
3  const { id } = await params;
4  const task = await prisma.task.findUnique({ where: { id } });
5  if (!task) return NextResponse.json({ error: "Not found" }, { status: 404 });
6  return NextResponse.json({ data: task });
7}

Layered Architecture¶

Keep handlers thin. Push database logic into a service layer:

Route handler → parse & validate request, choose status code Service → business logic + database queries ORM / SQL → data access

This separation makes each piece testable and keeps the same logic reusable from a CLI, a job, or another route.

Previous

HTTP Status Codes That Tell the Truth

Next

Connecting an ORM (Prisma) to Your Routes

Use ← → arrow keys to navigate between lessons