> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gocopper.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Routing

In Copper, each package that serves HTTP defines a **router**, which is any type that implements a single-method interface:

```go theme={null}
type Router interface {
	Routes() []chttp.Route
}
```

When the app starts, Copper collects every router into a single handler.

### Defining Routes

To add routes to a package, scaffold a router with the CLI:

```
copper scaffold:router rockets
```

This creates `pkg/rockets/router.go`, registers the router in `pkg/app/handler.go`, and adds it to the package's wire module. A router looks like this:

```go pkg/rockets/router.go theme={null}
type NewRouterParams struct {
	Logger clogger.Logger
}

func NewRouter(p NewRouterParams) *Router {
	return &Router{logger: p.Logger}
}

type Router struct {
	logger clogger.Logger
}

func (ro *Router) Routes() []chttp.Route {
	return []chttp.Route{
		{
			Path:    "/api/rockets",
			Methods: []string{http.MethodGet},
			Handler: ro.HandleListRockets,
		},
		{
			Path:    "/api/rockets/{id}",
			Methods: []string{http.MethodGet},
			Handler: ro.HandleGetRocket,
		},
	}
}
```

Handlers are plain `http.HandlerFunc`s. Anything your handlers need, such as services, a `*chttp.JSONReaderWriter`, or config, may be added as a field on `NewRouterParams`, and wire will inject it for you.

### Path Parameters

Parameters are declared in the path with `{name}` and read using `chttp.URLParams`:

```go theme={null}
func (ro *Router) HandleGetRocket(w http.ResponseWriter, r *http.Request) {
	var (
		ctx = r.Context()
		id  = chttp.URLParams(r)["id"]
	)

	// ...
}
```

You may also constrain a parameter with a regular expression; for example, `{id:[0-9]+}` only matches numeric IDs. Since routing is backed by [gorilla/mux](https://github.com/gorilla/mux), its full pattern syntax is available.

### Query Parameters

Query parameters may be read directly from the request:

```go theme={null}
status := r.URL.Query().Get("status")
```

### Route Matching

You never need to worry about the order in which routes are declared. Copper will automatically sort them so that deeper paths match first and literal segments take priority over parameters at the same depth. For example, `/rockets/featured` always wins over `/rockets/{id}`, while a catch-all such as `/{path:.*}` matches last.

### Registering Routers

`copper scaffold:router` handles this for you, but it is useful to know where routers live. The app's HTTP handler is assembled in `pkg/app/handler.go`:

```go pkg/app/handler.go theme={null}
func NewHTTPHandler(p NewHTTPHandlerParams) http.Handler {
	return chttp.NewHandler(chttp.NewHandlerParams{
		Routers: []chttp.Router{
			p.Rockets,
		},
		GlobalMiddlewares: []chttp.Middleware{
			chttp.SetRequestIDInCtxMiddleware(),
			p.DatabaseTxMW,
			p.RequestLoggerMW,
		},
		Logger: p.Logger,
	})
}
```

### Serving Under a Base Path

If you would like to mount your entire app under a prefix, you may set `base_path` in your config:

```toml theme={null}
[chttp]
base_path = "/admin"
```

Declare your route paths with the prefix included; Copper strips it at registration time.

<Note>
  When `base_path` is set, routes that don't start with the prefix are skipped. You may set `RegisterWithBasePath: true` on a route to have the prefix joined onto its path instead, which is how Copper's static file routes work.
</Note>
