Docs Router

Router

Routing is the act of deciding which handler receives a request.

In Plumego, the router is intentionally simple.

It does not try to infer intent,
does not scan packages,
does not generate routes implicitly,
and does not hide matching behavior.

If a request reaches a handler,
it is because you explicitly registered that route.


What the Router Does

The Plumego router has a narrow, well-defined responsibility:

  • Match incoming HTTP requests
  • Based on method + path
  • Dispatch exactly one handler
  • Or return a clear “not found” / “method not allowed” response

That is all.

Anything beyond this belongs elsewhere.


What the Router Does Not Do

The router deliberately does not:

  • Perform authentication
  • Perform authorization
  • Perform validation
  • Perform content negotiation
  • Perform dependency injection
  • Perform request transformation

Those concerns are handled by middleware and handlers.

Routing is selection, not decision-making.


Explicit Route Registration

All routes are registered explicitly in code.

Example (conceptual):

app := plumego.New()

app.GET("/health", HealthHandler)
app.POST("/orders", CreateOrderHandler)
app.POST("/orders/:id/cancel", CancelOrderHandler)

There is no auto-registration.

If a route exists, you can find it by searching the codebase.


Route Matching Model

Plumego routing is based on:

  • HTTP method
  • Path pattern

Common characteristics:

  • Static segments (/health)
  • Parameterized segments (/orders/:id)
  • No ambiguous matching
  • No priority tricks

If two routes could match the same request,
the router configuration is invalid.

Ambiguity is treated as a bug, not a feature.


Parameters Are Strings

Route parameters are always strings.

Example:

id := ctx.Param("id")

The router does not:

  • Parse types
  • Validate formats
  • Apply constraints

Type conversion and validation belong in handlers.

This keeps routing fast and predictable.


Router and HTTP Methods

Routes are method-specific.

This means:

  • GET /orders and POST /orders are different routes
  • Method mismatch is explicit
  • “Method Not Allowed” is not silently converted

This preserves HTTP semantics and avoids surprises.


Router as a Boundary

The router defines a hard boundary:

  • Before routing: transport concerns
  • After routing: application behavior

Handlers should assume:

  • The route matched intentionally
  • Required path parameters exist
  • Method is correct

They should not second-guess the router.


Grouping Routes Explicitly

Plumego allows explicit grouping for clarity and scope control.

Conceptual example:

admin := app.Group("/admin",
	AuthMiddleware(),
	AdminOnlyMiddleware(),
)

admin.GET("/stats", AdminStatsHandler)

Grouping is:

  • A readability tool
  • A scoping mechanism
  • A way to apply middleware explicitly

It is not a module system.


Router and Middleware Interaction

Middleware execution order is:

  1. Global middleware
  2. Group-level middleware
  3. Route handler

The router does not modify middleware behavior.

It simply determines which chain executes.

Routing decisions are made before handler execution begins.


No Implicit REST Conventions

Plumego does not enforce REST conventions.

It does not:

  • Generate CRUD routes
  • Assume resource semantics
  • Bind verbs to behavior

REST is an architectural style, not a router feature.

If you want RESTful APIs, you design them explicitly.


Error Handling at the Router Level

The router handles only routing errors:

  • Route not found → 404
  • Method not allowed → 405

All other errors are outside its scope.

This keeps error semantics clear and layered.


Router Predictability as a Feature

The router’s simplicity provides:

  • Fast mental parsing
  • Easy debugging
  • Low surprise factor
  • Stable behavior across versions

You never have to wonder:

“Why did this request go there?”

The answer is always in the route table.


Testing Routing Behavior

Because routing is explicit:

  • You can test routes with standard HTTP tests
  • There is no hidden behavior to mock
  • Route coverage is straightforward

Routing bugs are configuration bugs — and easy to find.


Common Anti-Patterns

Route Registration via Reflection

This hides behavior and breaks predictability.


Encoding Business Logic in Paths

Paths describe access points, not workflows.


Overusing Wildcards

Overly generic routes reduce clarity and safety.


Why Plumego Keeps Routing Boring

Routing is foundational infrastructure.

The more “smart” it becomes,
the harder systems are to reason about.

Plumego chooses boring routing because:

Predictability scales better than cleverness.


Summary

In Plumego:

  • Routing is explicit
  • Matching is deterministic
  • Parameters are strings
  • Behavior is visible in code
  • No hidden conventions exist

The router selects handlers — nothing more.


Next

With routing understood, the final Core concept is:

→ Middleware

This explains how Plumego controls execution flow around handlers — explicitly and predictably.