DynamicRoutes.Dispatch (DynamicRoutes v0.1.0)

Copy Markdown View Source

The request-time half: decide, rewrite, and restore.

Kept out of the use DynamicRoutes macro so that what gets injected into a host router is three lines rather than an implementation. A bug fixed here is fixed by upgrading the dependency, not by recompiling somebody's router.

Summary

Functions

Whether this request was routed dynamically rather than by a declared route.

The path segments the internal catch-all route was registered under.

Decides what should happen to a request.

What the resolver returned for this request, or nil.

Puts the client's own path back on a rewritten conn.

Functions

dynamic?(conn)

@spec dynamic?(Plug.Conn.t()) :: boolean()

Whether this request was routed dynamically rather than by a declared route.

internal_segments(router)

@spec internal_segments(module()) :: [String.t()]

The path segments the internal catch-all route was registered under.

Read back from the router's own route table rather than assumed, so that declaring it inside a scope — scope "/admin" — still works: the rewrite has to produce whatever path the route actually ended up at, not the one that was configured before the scope was applied.

prepare(conn, router, resolver)

@spec prepare(Plug.Conn.t(), module(), module()) :: {:rewrite, Plug.Conn.t()} | :pass

Decides what should happen to a request.

Returns {:rewrite, conn} with a conn whose path points at the internal route, or :pass to let the router handle the request untouched.

The order is the whole point: a path that matches a declared route is passed through before the resolver is consulted at all. That is what makes declaration order stop mattering — a database page can never shadow a route in the router, whichever was written first, because the router is asked first and only its misses go any further.

resolution(conn)

@spec resolution(Plug.Conn.t()) :: term() | nil

What the resolver returned for this request, or nil.

restore_path(conn)

@spec restore_path(Plug.Conn.t()) :: Plug.Conn.t()

Puts the client's own path back on a rewritten conn.

Called by DynamicRoutes.Dispatcher after the pipeline has run and before the controller does, so the controller never observes the internal path.