Sure — here is the same blog as a clean .md Markdown document:
Before You Code the Backend, Design It on Paper
Let’s be honest.
When we start a new project, the first thing most developers want to do is open VS Code, create a server folder, install a few packages, and start cooking.
bash
npm install express
And boom — apparently we’re building the next billion-dollar startup.
Except… we haven't decided what the backend actually needs to do yet.
That’s where things usually get messy.
A backend isn't just about writing APIs. Before writing a single route, controller, model, or database query, you should have a rough idea of how the whole system is going to work.
And surprisingly, one of the best tools for doing that isn't some fancy AI architecture tool.
It's paper.
Yes. Actual paper.
---
Start With the Problem, Not the Framework
Before thinking about Express, Next.js, NestJS, Django, Laravel, or whatever framework is trending this week, ask:
> What does my system actually need to do?
Imagine you're building an event management platform.
Don't immediately write:
POST /api/events
GET /api/events
DELETE /api/events/:id
Instead, grab a piece of paper and write down the actual workflow.
For example:
User
↓
Creates account
↓
Creates event
↓
Adds event details
↓
Publishes event
↓
Other users discover event
↓
User registers
That's already telling you a lot.
You can now start thinking about what information the backend needs to store and which parts of the system communicate with each other.
The code comes later.
First, understand the game.
---
Step 1: Identify Your Actors
Start by writing down who interacts with your system.
For example:
User
Admin
Organizer
Payment Provider
Email Service
Not every project needs all of these.
A small project might simply have:
User
Admin
That's fine.
The goal isn't to make your architecture look impressive.
The goal is to understand who is doing what.
For every actor, ask:
> What can this person or system actually do?
For example:
User
Register
Login
View events
Register for event
Cancel registration
Admin
Login
Create event
Edit event
Delete event
View registrations
Already, your API requirements are starting to appear naturally.
---
Step 2: Turn Actions Into Resources
Now take those actions and identify the things your backend actually manages.
For our event platform:
Users
Events
Registrations
These are likely to become database entities.
You might sketch:
USER
---------
id
name
email
password
role
EVENT
---------
id
title
description
date
location
organizerId
REGISTRATION
---------
id
userId
eventId
createdAt
And suddenly you're doing database design without even opening your database tool.
Pretty neat.
---
Step 3: Draw the Relationships
This is where the paper starts getting interesting.
Connect your entities.
USER
│
│ creates
↓
EVENT
│
│ has
↓
REGISTRATION
↑
│
USER
Then think about the relationship more carefully.
One user can register for many events.
One event can have many registrations.
So:
User 1 ──────── * Registration
Event 1 ─────── * Registration
That tells you something important:
Registration isn't just some random table.
It's basically the bridge between users and events.
These little decisions become extremely important once your database grows.
---
Step 4: Plan the API on Paper
Only after understanding the resources should you start thinking about endpoints.
Now you can write:
AUTH
POST /auth/register
POST /auth/login
EVENTS
GET /events
GET /events/:id
POST /events
PATCH /events/:id
DELETE /events/:id
REGISTRATIONS
POST /events/:id/register
GET /users/me/registrations
DELETE /registrations/:id
Notice something.
We didn't start with:
> "What API routes should I create?"
We started with:
> "What does my system need to do?"
The API simply came out of that answer.
That's the difference between designing a backend and just making endpoints until the frontend stops complaining.
---
Step 5: Think About Authentication
Now ask:
> Who is allowed to do what?
For example:
Guest
↓
Can view events
User
↓
Can register for events
Organizer
↓
Can create/manage own events
Admin
↓
Can manage everything
Put that on paper.
You might sketch:
┌──────────────┐
│ ADMIN │
└──────┬───────┘
│
Full Access
│
┌───────────────┼───────────────┐
↓ ↓ ↓
Users Events Registrations
┌──────────────┐
│ USER │
└──────┬───────┘
│
View + Register
Now you're thinking about authorization before accidentally giving every logged-in user admin powers.
Classic backend disaster avoided.
---
Step 6: Design the Request Flow
This is one of my favorite things to do on paper.
Take one important action and follow it from beginning to end.
For example:
User registers for an event.
Draw:
Frontend
↓
POST /events/:id/register
↓
Authentication
↓
Validate Event
↓
Check Existing Registration
↓
Create Registration
↓
Database
↓
Response
↓
Frontend
This tiny diagram tells you what your backend actually needs to do.
You can then break it down.
1. Authentication
Is the user logged in?
No → 401 Unauthorized
Yes → Continue
2. Validate Event
Does the event exist?
No → 404 Not Found
Yes → Continue
3. Check Duplicate Registration
Has this user already registered?
Yes → Return error
No → Continue
4. Create Registration
Store:
userId
eventId
createdAt
5. Return Response
{
"message": "Registration successful"
}
Now when you finally write the code, you're not figuring out the architecture while simultaneously fighting syntax errors.
---
Step 7: Think About Errors Before They Happen
Another underrated part of backend planning is deciding:
> What happens when things go wrong?
Because things will go wrong.
The database will fail.
The user will send nonsense.
Someone will call an endpoint they shouldn't.
Someone will somehow send:
{
"email": "hello"
}
and expect your backend to understand their life choices.
Plan the common failures:
400 → Invalid request
401 → Not authenticated
403 → Not authorized
404 → Resource doesn't exist
409 → Conflict
500 → Server error
You don't need to plan every possible disaster.
Just identify the important ones.
---
Step 8: Decide Where the Logic Lives
This is where your paper architecture starts becoming more technical.
For example:
Request
↓
Route
↓
Controller
↓
Service
↓
Database
You might write:
POST /events/:id/register
↓
Controller
↓
Registration Service
↓
Database
The controller shouldn't become a 700-line monster containing authentication, validation, business logic, database queries, email sending, and probably your grocery list.
Keep responsibilities separated.
A simple architecture might look like:
Routes
↓
Controllers
↓
Services
↓
Repositories / Database
You don't always need every layer.
The architecture should match the project.
Not your desire to make a CRUD app look like NASA's internal infrastructure.
---
Step 9: Plan the Database Properly
Now go deeper.
For each entity, write:
Field
Type
Required?
Unique?
Relationship?
For example:
USER
id UUID PK
name string required
email string unique
password string required
role enum required
createdAt datetime required
Then think about indexes.
For example, if you'll frequently search users by email:
email → INDEX
If registrations are frequently searched by event:
eventId → INDEX
You don't need to become a database wizard before starting your project.
But thinking about these things early prevents painful restructuring later.
---
Step 10: Draw the Whole Backend
Now zoom out.
Put everything together:
┌─────────────┐
│ Frontend │
└──────┬──────┘
│
HTTP/API
│
↓
┌─────────────────┐
│ Backend │
│ │
│ Auth │
│ Events │
│ Registrations │
└────────┬────────┘
│
↓
┌─────────────────┐
│ Database │
└─────────────────┘
Then add external services if needed:
┌──────────────┐
│ Frontend │
└──────┬───────┘
│
↓
┌──────────────┐
│ Backend │
└──┬────┬───┬──┘
│ │ │
↓ ↓ ↓
DB Email Storage
Now you have an actual mental model of your system.
---
And This Is Where AI Becomes Useful
AI is great at helping you challenge your architecture.
But don't let AI design your entire backend while you sit there like:
> "Sure bro, looks good."
Instead, make your own design first.
Draw it.
Think about it.
Then give it to AI.
For example:
> "Here is my backend architecture. Review it. Don't redesign it immediately. Identify missing relationships, security issues, scalability problems, and unnecessary complexity."
That's a much better use of AI.
You remain the architect.
AI becomes the annoying senior developer who keeps asking:
> "What happens if this fails?"
And honestly, that's useful.
---
The Paper Test
Before writing code, try answering these questions on paper.
System
What problem does the backend solve?
Who uses it?
What can each type of user do?
Database
What are the main entities?
How are they related?
Which fields are required?
Which fields should be unique?
API
What resources exist?
What endpoints are required?
What HTTP methods are used?
Authentication
How does a user authenticate?
What roles exist?
What can each role access?
Business Logic
What happens during each major action?
What validations are required?
What happens if something fails?
Architecture
Where does each piece of logic live?
What external services are involved?
Where does data flow?
If you can answer these questions without touching your keyboard, you're already halfway there.
---
Don't Over-Engineer It
There's another trap.
Once developers learn architecture, they sometimes go completely off the rails.
You ask for a simple todo app and somehow get:
Microservices
↓
API Gateway
↓
Message Queue
↓
Event Bus
↓
Redis
↓
Kubernetes
↓
Three databases
↓
Distributed tracing
↓
NASA
Bro.
It's a todo app.
Start with what the project actually needs.
A small application might only need:
Frontend
↓
Backend
↓
Database
And that's perfectly fine.
Good architecture isn't the architecture with the most boxes.
It's the architecture where the boxes make sense.
---
The Real Benefit of Designing on Paper
The biggest advantage isn't that your code will be perfect.
It won't.
Requirements will change.
You'll discover new edge cases.
You'll probably change your database schema halfway through the project anyway.
That's normal.
The benefit is that you're thinking before typing.
When you design first, you catch problems while they're cheap.
Changing a box on paper takes five seconds.
Changing a database schema after you've built authentication, APIs, frontend integration, seed scripts, and production data?
Yeah…
That's a different conversation.
---
Final Thought
Backend development isn't just:
Write API
→ Connect database
→ Fix error
→ Google error
→ Ask AI
→ Fix another error
→ Somehow it works
That's development by survival.
A better approach is:
Understand
↓
Design
↓
Draw
↓
Question
↓
Validate
↓
Code
↓
Test
↓
Improve
You don't need a giant architecture document.
Sometimes a notebook, a pen, a few boxes, some arrows, and a slightly questionable amount of coffee are enough.
Design the system first. Then make the code catch up with your thinking.
Top comments (0)