POST /createUser, GET /deleteUser?id=123, POST /getUserList, and my personal favorite: GET /api/v1/doEverything?type=refund&userId=456&amount=99.99
Six months later we rewrote the entire API. Customer churn dropped 31%. Support tickets fell 64%. The mobile team sent me actual champagne.
The difference? Eight non-negotiable rules I now enforce in every code review — the ones that separate seniors who ship APIs people love from beginners who create endpoints people curse.
Here they are, with the war stories that taught me each one.
1. Resources Are Nouns, Never Verbs
Beginners: GET /getUsers, POST /deleteOrder
Seniors: GET /users, DELETE /orders/123
I once saw a junior defend GET /sendEmail for 20 minutes.
I asked: "What happens when we need to resend?"
Silence.
Rule: Your URL bar should read like a sentence in English.
2. Plural Nouns Only (Yes, Always)
/user vs /users
Beginners think it's bikeshedding.
Seniors know consistency removes cognitive load across 400 endpoints.
We chose plural in 2018 and never looked back. Pick one and tattoo it on your soul.
3. Never Expose Database IDs to Clients
Beginners return the auto-increment id from PostgreSQL.
Seniors use UUIDs or opaque tokens (cust_01H...).
Why? Sequential IDs leak cardinality and enable enumeration attacks.
We caught a scraper pulling 2 million user records in one weekend because someone used userId=1,2,3...
4. HTTP Methods Must Match the Action — No Exceptions
I've seen POST /users/123/activate when it should be POST /users/123/activation.
Worse: GET /users/123/delete.
Rule: If it changes state → POST/PUT/PATCH/DELETE.
If it only reads → GET.
Your future self debugging at 2 AM will thank you.
5. Version in the URL (Yes, Really)
/api/v1/users not headers, not subdomains.
Beginners hate it ("it's ugly").
Seniors know the day you need to break a contract, you'll be glad v1 and v2 live side-by-side.
We run v1 through v7 today. Zero forced client upgrades.
6. Error Responses Are Predictable JSON, Always
Beginners return HTML, plain text, or random fields. Seniors return:
{
"error": "INSUFFICIENT_FUNDS",
"message": "Account balance too low",
"detail": "Required: 100.00 USD, available: 3.42 USD",
"requestId": "req_01H..."
}Mobile and frontend teams will love you forever.
7. Filtering, Sorting, Pagination — Done Right
Beginners invent syntax every endpoint.
Seniors use the same pattern everywhere:
GET /orders?status=shipped&sort=-createdAt&page=3&limit=50
We saved 14 custom parser bugs by enforcing this single convention.
8. Bonus Senior Move: Design the API Contract First
We now write OpenAPI spec → generate backend stubs + client SDKs + Postman collection → implement. Result: 80% fewer "but the API doesn't do what I expected" tickets. The mobile team finishes before we do.
The Day I Became "That Guy"
Early in my career I built POST /processPaymentAndSendEmailAndUpdateInventory.
It passed review (somehow).
It broke in production 47 minutes after launch.
I still get reminded of it in every retro.
That pain birthed these eight rules. They're now in our engineering handbook with my name attached — equal parts pride and penance.
Final Truth
You don't become a senior engineer by knowing Spring Security or Kubernetes. You become one when your API feels obvious to someone who's never seen your code.
These eight rules are the fastest way I know to get there.
Break one → you're still learning. Live by all eight → clients send you champagne.
Which rule are you breaking right now? Drop the number below — no judgment, just curiosity (and I reply to every confession).