ๆƒฏๆ€ง่šๅˆ ้ซ˜ๆ•ˆ่ฟฝ่ธชๅ’Œ้˜…่ฏปไฝ ๆ„Ÿๅ…ด่ถฃ็š„ๅšๅฎขใ€ๆ–ฐ้—ปใ€็ง‘ๆŠ€่ต„่ฎฏ
้˜…่ฏปๅŽŸๆ–‡ ๅœจๆƒฏๆ€ง่šๅˆไธญๆ‰“ๅผ€

ๆŽจ่่ฎข้˜…ๆบ

aimingoo็š„ไธ“ๆ 
aimingoo็š„ไธ“ๆ 
Google DeepMind News
Google DeepMind News
S
SegmentFault ๆœ€ๆ–ฐ็š„้—ฎ้ข˜
Project Zero
Project Zero
D
DataBreaches.Net
I
InfoQ
L
Lohrmann on Cybersecurity
OSCHINA ็คพๅŒบๆœ€ๆ–ฐๆ–ฐ้—ป
OSCHINA ็คพๅŒบๆœ€ๆ–ฐๆ–ฐ้—ป
้…ท ๅฃณ โ€“ CoolShell
้…ท ๅฃณ โ€“ CoolShell
Stack Overflow Blog
Stack Overflow Blog
The Register - Security
The Register - Security
Recorded Future
Recorded Future
Vercel News
Vercel News
ๅš
ๅšๅฎขๅ›ญ - ๅธๅพ’ๆญฃ็พŽ
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
I
Intezer
The Hacker News
The Hacker News
F
Fortinet All Blogs
Microsoft Azure Blog
Microsoft Azure Blog
P
Proofpoint News Feed
Help Net Security
Help Net Security
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Scott Helme
Scott Helme
T
Threatpost
็ˆฑ่Œƒๅ„ฟ
็ˆฑ่Œƒๅ„ฟ
N
Netflix TechBlog - Medium
D
Docker
ไบ‘้ฃŽ็š„ BLOG
ไบ‘้ฃŽ็š„ BLOG
C
Cisco Blogs
K
Kaspersky official blog
H
Help Net Security
S
Secure Thoughts
T
Threat Research - Cisco Blogs
้’›ๅช’ไฝ“๏ผšๅผ•้ข†ๆœชๆฅๅ•†ไธšไธŽ็”Ÿๆดปๆ–ฐ็Ÿฅ
้’›ๅช’ไฝ“๏ผšๅผ•้ข†ๆœชๆฅๅ•†ไธšไธŽ็”Ÿๆดปๆ–ฐ็Ÿฅ
S
Security @ Cisco Blogs
Cyberwarzone
Cyberwarzone
N
News and Events Feed by Topic
G
Google Developers Blog
Forbes - Security
Forbes - Security
ๅš
ๅšๅฎขๅ›ญ - ไธ‰็”Ÿ็ŸณไธŠ(FineUIๆŽงไปถ)
ๅš
ๅšๅฎขๅ›ญ - ๅถๅฐ้’—
B
Blog
Google DeepMind News
Google DeepMind News
Recent Announcements
Recent Announcements
Simon Willison's Weblog
Simon Willison's Weblog
S
Securelist
P
Privacy International News Feed
Spread Privacy
Spread Privacy
The Last Watchdog
The Last Watchdog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Donโ€™t Fail โ€” They Drift Spilling beans for how i learn for exam๐Ÿ˜"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" โ€” What Actually Happened Comfy Cloudโ€™s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions โ€” here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components โ€” Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cรณmo construรญ un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 ๐Ÿš€ I Built an Ethical Hacking Scanner Tool โ€“ Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points โ€” Here's What I Found About How Markets Really Move EcoTrack AI โ€” Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead โ€” I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve โ€” no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like Youโ€™re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace โ€” how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025โ€“62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D โ€” A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent โ€” It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly โ€” 2026/04/10โ€“04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI ้€ฑๅ ฑ โ€” 2026/04/10โ€“2026/04/17 ๆจกๅž‹ๅฐ้Ž–ๆฝฎไพ†ไบ†๏ผŒไฝ†ๅทฅๅ…ท้ˆๆ‰ๆ˜ฏ็œŸๆˆฐๅ ด Maybe this is how Open-Source apps are born... ๐Ÿš€ Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge โ€” $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase โ€” Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train โ€” Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extraรงรฃo de Vรญdeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life โ€” Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 โ€” Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows โ€” Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTrackingๅฎ‰่ฃ…ๅ’ŒiPhone้ขๆ•้…็ฝฎๆ•™็จ‹๏ผŒๆœ‰bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
๐Ÿ›ฃ๏ธ Routing in Backend Development โ€” The Complete Developer's Guide
PRABHANSH TI ยท 2026-05-01 ยท via DEV Community

You've probably typed GET /api/users a hundred times. But do you really know what's happening under the hood when a request hits your server and somehow finds its way to the right function?

Routing is one of those fundamentals that every backend dev uses daily but rarely sits down to understand deeply. This guide fixes that. We'll go from the basics all the way to versioning, middleware, and the unsung hero โ€” the catch-all route.

Let's get into it.


๐Ÿง  What Even Is Routing?

At its core, routing is the system that maps an incoming HTTP request to the correct piece of server-side logic (called a handler) that should process it.

Think of it like a post office. A letter (request) comes in. The post office (router) reads two things: what kind of delivery is this and where is it going. Then it hands the letter to the right person (handler).

Every route is defined by two things:

Part Expressed By Meaning
What do you want to do? HTTP Method (GET, POST, PUT, DELETE) Your intent
Where do you want to do it? URL Path (/api/books) The resource
GET /api/users
 โ”‚       โ”‚
 โ”‚       โ””โ”€โ”€ WHERE: the users resource
 โ””โ”€โ”€ WHAT: I want to read data

Enter fullscreen mode Exit fullscreen mode

The server combines both pieces and fires the right handler โ€” which runs business logic, talks to the database, and returns a response.

Simple enough. But routing gets a lot more nuanced from here.


1. Static Routes โ€” The Foundation

A static route is the simplest kind โ€” the URL path is fixed, constant, never changes.

GET   /api/books   โ†’  Returns a list of all books
POST  /api/books   โ†’  Creates a new book

Enter fullscreen mode Exit fullscreen mode

Notice something? Both use /api/books but they're two completely different routes because the HTTP method is different. The method is what differentiates them.

GET  /api/books  โ”€โ”
                   โ”œโ”€โ”€ TWO different routes
POST /api/books  โ”€โ”˜

Enter fullscreen mode Exit fullscreen mode

Static routes are the bread and butter. They're predictable, easy to document, and easy to test. Always reach for them when you're working with a collection of resources.


2. Dynamic Routes & Path Parameters โ€” Targeting Specific Resources

Static routes are great for collections. But what if you want data for one specific user? You don't want all 50,000 users โ€” just the one with ID 123.

That's where dynamic routes come in. You embed a variable directly in the URL path:

GET /api/users/123
                โ””โ”€โ”€ This is the dynamic part โ€” the user's ID

Enter fullscreen mode Exit fullscreen mode

On the server side, you define this with a path parameter (also called a route parameter):

// The colon (:) before "id" tells the router:
// "treat this segment as a variable, accept any value here"

router.get("/api/users/:id", (req, res) => {
  const userId = req.params.id; // "123" when hitting /api/users/123

  // Fetch this specific user from the DB
  const user = db.users.findById(userId);
  res.json(user);
});

Enter fullscreen mode Exit fullscreen mode

Heads up: Even if the value looks like a number (123), it arrives as a string in req.params. Always parse it if you need a number: parseInt(req.params.id) or Number(req.params.id).

You can also have multiple path parameters in a single route:

router.get("/api/users/:userId/posts/:postId", handler);
// /api/users/42/posts/7 โ†’ { userId: "42", postId: "7" }

Enter fullscreen mode Exit fullscreen mode


3. Query Parameters โ€” Filtering, Sorting, Pagination

Here's something that trips up a lot of junior devs: GET requests don't have a body. So how do you send extra data like "give me page 2" or "filter by active users"?

You use query parameters โ€” key-value pairs tacked onto the end of a URL after a ?.

/api/books?page=2&limit=20&sort=asc
           โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
           query parameters (after ?)

Enter fullscreen mode Exit fullscreen mode

Multiple params are separated by &. Here are the most common real-world uses:

# Pagination
GET /api/books?page=2&limit=20

# Filtering
GET /api/users?status=active&role=admin

# Sorting
GET /api/products?sort=price&order=desc

# Search
GET /api/search?query=javascript+closures

Enter fullscreen mode Exit fullscreen mode

On the server side, you access them via req.query:

router.get("/api/books", (req, res) => {
  const { page = 1, limit = 10, sort = "createdAt" } = req.query;

  const books = db.books.findAll({ page, limit, sort });
  res.json(books);
});

Enter fullscreen mode Exit fullscreen mode

Path Param vs Query Param โ€” The Rule of Thumb

This is one of the most common sources of confusion. Here's the mental model:

/api/users/123/posts?page=2&sort=desc
           โ”‚             โ”‚
           โ”‚             โ””โ”€โ”€ Query Params โ†’ extra metadata
           โ”‚                 (filters, pagination, sorting, search)
           โ”‚
           โ””โ”€โ”€ Path Param โ†’ part of the resource identity
               (which specific user? user 123)

Enter fullscreen mode Exit fullscreen mode

Use Case Use
Identifying a specific resource Path param: /users/123
Filters, sorting, pagination, search Query param: ?status=active

If you tried using path params for search:

/api/search/javascript+closures   โŒ Weird, hard to maintain
/api/search?query=javascript      โœ… Clean, correct, idiomatic

Enter fullscreen mode Exit fullscreen mode


4. Nested Routes โ€” Expressing Relationships

APIs often deal with resources that belong to other resources. A post belongs to a user. A comment belongs to a post. How do you express that in your URLs?

With nested routes โ€” chaining resources together in the path to show hierarchy:

/api/users/123/posts/456
      โ”‚    โ”‚    โ”‚    โ”‚
      โ”‚    โ”‚    โ”‚    โ””โ”€โ”€ Specific post (ID 456)
      โ”‚    โ”‚    โ””โ”€โ”€ "posts" resource (child of user)
      โ”‚    โ””โ”€โ”€ Specific user (ID 123)
      โ””โ”€โ”€ "users" resource

Enter fullscreen mode Exit fullscreen mode

Each level maps to a completely different handler:

router.get("/api/users", getAllUsers);
// โ†’ Returns all users

router.get("/api/users/:userId", getUserById);
// โ†’ Returns user 123

router.get("/api/users/:userId/posts", getPostsByUser);
// โ†’ Returns all posts *by* user 123

router.get("/api/users/:userId/posts/:postId", getSinglePost);
// โ†’ Returns the specific post 456 by user 123

Enter fullscreen mode Exit fullscreen mode

Nested routes make your API self-documenting. A developer reading /api/orders/89/items/3 immediately understands: "item 3 from order 89." No documentation needed.

A word of caution though โ€” don't go deeper than 2โ€“3 levels. Beyond that, URLs become unwieldy and hard to work with:

/api/orgs/1/teams/5/projects/12/tasks/89/comments/3   โŒ Too deep
/api/tasks/89/comments/3                               โœ… Flatten it

Enter fullscreen mode Exit fullscreen mode


5. HTTP Methods โ€” More Than Just GET and POST

Most devs know GET and POST, but a well-designed REST API uses the full suite of HTTP methods to communicate intent:

Method Purpose Example
GET Read / fetch data GET /api/users
POST Create a new resource POST /api/users
PUT Replace a resource entirely PUT /api/users/123
PATCH Partially update a resource PATCH /api/users/123
DELETE Remove a resource DELETE /api/users/123

The difference between PUT and PATCH catches a lot of people:

// PUT โ€” you send the ENTIRE object, it replaces everything
PUT /api/users/123
Body: { "name": "John", "email": "john@new.com", "role": "admin" }

// PATCH โ€” you send only the fields you want to change
PATCH /api/users/123
Body: { "email": "john@new.com" }

Enter fullscreen mode Exit fullscreen mode

Using the right HTTP method isn't just semantics โ€” it affects caching, idempotency, and how frontend developers consuming your API will reason about it.


6. Route Versioning โ€” Managing Breaking Changes Gracefully

Here's a scenario every backend dev will face eventually. Your API is live. Clients (mobile apps, frontend teams, third-party integrations) are consuming it. And now you need to change the shape of a response in a way that would break existing clients.

What do you do? You version your routes:

GET /api/v1/products    โ†’  Old response format
GET /api/v2/products    โ†’  New response format

Enter fullscreen mode Exit fullscreen mode

Both live simultaneously. Old clients keep using v1 without breaking. New clients adopt v2 on their own timeline.

Here's a concrete example. Your v1 endpoint returns:

{ "id": 1, "name": "Laptop", "price": 999 }

Enter fullscreen mode Exit fullscreen mode

v2 needs to rename name to title (breaking change for anyone reading the name field):

{ "id": 1, "title": "Laptop", "price": 999 }

Enter fullscreen mode Exit fullscreen mode

The Versioning Workflow

1. Ship v2 alongside v1 (both work simultaneously)
         โ†“
2. Announce to all consumers: "v1 is now DEPRECATED"
         โ†“
3. Give teams a migration window (2โ€“4 weeks is typical)
         โ†“
4. All clients migrate from v1 โ†’ v2
         โ†“
5. Shut down v1

Enter fullscreen mode Exit fullscreen mode

This is professional, considerate API design. It's the difference between a reliable API and one that breaks people's apps on a Tuesday morning.


7. Middleware โ€” The Unsung Hero of Routing

Routing doesn't just mean "request hits handler." In real apps, requests pass through a pipeline of middleware functions before reaching the handler.

Middleware is a function that sits between the router and your handler. It can:

  • Authenticate the request (is this user logged in?)
  • Log the request
  • Parse the request body
  • Validate input
  • Rate-limit the caller
  • And more...
// Middleware runs BEFORE the handler
const authenticate = (req, res, next) => {
  const token = req.headers.authorization;

  if (!token) {
    return res.status(401).json({ error: "Unauthorized" });
  }

  req.user = verifyToken(token); // attach user to request
  next(); // pass control to the next middleware or handler
};

// Apply middleware to a specific route
router.get("/api/profile", authenticate, (req, res) => {
  // req.user is available here because middleware set it
  res.json(req.user);
});

// Or apply to all routes in a group
router.use("/api/admin", authenticate, adminRateLimiter);

Enter fullscreen mode Exit fullscreen mode

Think of middleware as a series of gates a request must pass through. Any gate can stop the request (return an error) or let it continue (next()). This keeps your handlers clean and focused on business logic.


8. The Catch-All Route โ€” Your Safety Net

What happens when someone hits a route that doesn't exist? Like /api/v3/products on a server that only has v1 and v2?

Without a catch-all, the server might return an empty response, a confusing framework error, or even crash in some setups. Not great.

The catch-all route is your last line of defense. Define it at the very end of all your routes:

// All real routes defined first
router.get("/api/v1/products", getProductsV1);
router.get("/api/v2/products", getProductsV2);
router.get("/api/users", getAllUsers);
// ... all other routes ...

// Catch-all โ€” MUST be last
// The asterisk (*) matches anything that hasn't been caught above
router.all("*", (req, res) => {
  res.status(404).json({
    error: "Route not found",
    message: `The endpoint '${req.url}' does not exist on this server.`
  });
});

Enter fullscreen mode Exit fullscreen mode

Why must it be last? Because routes are evaluated in order. If you put the catch-all first, it swallows every request before any real routes get a chance to match.

A good 404 response is developer-friendly โ€” tell them what wasn't found. It saves hours of debugging.


9. RESTful Route Design Patterns โ€” The Conventions You Should Follow

When designing routes, there are widely accepted conventions that make your API feel familiar to any developer:

# โœ… Use nouns for resources, not verbs
GET /api/users         โœ…
GET /api/getUsers      โŒ  (verb in URL)

# โœ… Use plural nouns
GET /api/users         โœ…
GET /api/user          โŒ  (inconsistent)

# โœ… Use lowercase and hyphens, not camelCase
GET /api/blog-posts    โœ…
GET /api/blogPosts     โŒ

# โœ… Actions on a resource use HTTP methods, not URL verbs
DELETE /api/users/123         โœ…
GET    /api/users/123/delete  โŒ

# โœ… Non-CRUD actions? Use a sub-resource or action endpoint
POST /api/orders/89/cancel    โœ…
POST /api/payments/55/refund  โœ…

Enter fullscreen mode Exit fullscreen mode

Following these conventions means any developer reading your API docs will immediately understand the structure, even if they've never seen your code before.


10. Quick Reference

Here's everything in one place:

Concept Example Use For
Static Route GET /api/books Fixed resource, always the same path
Dynamic Route GET /api/users/:id Targeting a specific resource
Path Parameter /users/123 โ†’ :id = "123" Resource identity
Query Parameter ?page=2&sort=desc Filters, pagination, sorting, search
Nested Route /users/123/posts/456 Parent-child resource relationships
Route Versioning /api/v1/ vs /api/v2/ Breaking changes without breaking clients
Middleware authenticate, rateLimit Cross-cutting concerns before the handler
Catch-All Route /* Graceful 404 for unknown routes

The Mental Model to Remember

Incoming Request
       โ”‚
       โ–ผ
  Middleware Pipeline
  (auth, logging, validation...)
       โ”‚
       โ–ผ
     Router
  (matches method + path)
       โ”‚
    โ”Œโ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
    โ”‚  /api/v2/users/:id/posts?page=2&sort=desc   โ”‚
    โ”‚            โ”‚                 โ”‚              โ”‚
    โ”‚       Path Param          Query Params      โ”‚
    โ”‚    (specific resource)   (request metadata) โ”‚
    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
       โ”‚
       โ–ผ
    Handler
  (business logic + DB)
       โ”‚
       โ–ผ
    Response

Enter fullscreen mode Exit fullscreen mode

Routing is the backbone of every web API. Get these fundamentals right, and you'll build APIs that are predictable, maintainable, and a joy for other developers to consume.


Happy building. ๐Ÿš€