feat(14.2.1-01): add optional surf LocaleResolver seam
Look up a backpack-published resolver so a compiled translate plugin can strip an enabled URL prefix and write a validated locale onto context. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -35,13 +35,14 @@ In Go the same declaration is a `pact.HasRoutes` method. Paths use Go `http.Serv
|
||||
|
||||
surf wraps every non-raw route in the same layers. From the outside in:
|
||||
|
||||
1. CORS, only for the paths configured under `http.cors.paths`, including preflight requests.
|
||||
2. Panic recovery. A panic becomes an opaque JSON 500 from [wire](../../modules/wire/README.md), and because the response is buffered until the handler returns, the client never receives half a body.
|
||||
3. The request locale, taken from the `Accept-Language` header and stored in the context.
|
||||
4. The body limit: `http.body_limits.default_bytes`, or the route's own `body.limit:<bytes>`.
|
||||
5. The route's middleware, in the order you listed them: group middleware first, then the route's own.
|
||||
6. The path constraints. A request whose parameter fails `pact.Router.Where` or `pact.Router.WhereIn` gets a 404 before your handler runs.
|
||||
7. Your handler.
|
||||
1. Optional locale-prefix rewrite, when a `surf.LocaleResolver` is published: an enabled locale as the first path segment is stripped so later layers and routing see the unprefixed path.
|
||||
2. CORS, only for the paths configured under `http.cors.paths`, including preflight requests.
|
||||
3. Panic recovery. A panic becomes an opaque JSON 500 from [wire](../../modules/wire/README.md), and because the response is buffered until the handler returns, the client never receives half a body.
|
||||
4. The request locale, taken from the published `surf.LocaleResolver` when one exists, or from the `Accept-Language` header otherwise, and stored in the context.
|
||||
5. The body limit: `http.body_limits.default_bytes`, or the route's own `body.limit:<bytes>`.
|
||||
6. The route's middleware, in the order you listed them: group middleware first, then the route's own.
|
||||
7. The path constraints. A request whose parameter fails `pact.Router.Where` or `pact.Router.WhereIn` gets a 404 before your handler runs.
|
||||
8. Your handler.
|
||||
|
||||
Raw groups, declared with `pact.Router.GroupRaw`, are for webhooks and file streams. They skip the default body limit, refuse house middleware, and a panic in them returns a bare 500.
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ for _, n := range []int{0, 1, 7} {
|
||||
|
||||
## The request locale
|
||||
|
||||
The locale lives on the request context, not in a global. For every route, [surf](../../modules/surf/README.md) sets it from the `Accept-Language` header; the `locale.from-principal` middleware switches it to the signed-in user's preferred locale. Code reads it with `towel.Locale`, and code outside a request sets it with `towel.WithLocale`, as the example above does. A context without a locale uses `app.locale`.
|
||||
The locale lives on the request context, not in a global. For every route, [surf](../../modules/surf/README.md) looks up an optional `surf.LocaleResolver` published by a compiled plugin and writes that validated code with `towel.WithLocale`. When no resolver is published, surf sets the locale from the `Accept-Language` header and the `locale.from-principal` middleware can switch it to the signed-in user's preferred locale. Code reads it with `towel.Locale`, and code outside a request sets it with `towel.WithLocale`, as the example above does. A context without a locale uses `app.locale`.
|
||||
|
||||
## Strings for the admin
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ The framework registers these names:
|
||||
| `locale.from-principal` | Switches the request locale to the signed-in user's preferred locale. |
|
||||
| `backend` | The admin guard, when the admin is enabled. |
|
||||
|
||||
Every route also gets, around its own middleware, JSON panic recovery, the request locale from `Accept-Language`, the body limit from `http.body_limits.default_bytes`, and CORS headers when its path matches `http.cors.paths`. The order is described in [Request lifecycle](../architecture/request-lifecycle.md).
|
||||
Every route also gets, around its own middleware, JSON panic recovery, the request locale from a published [`surf.LocaleResolver`](../../modules/surf/README.md) or from `Accept-Language` when none is published, the body limit from `http.body_limits.default_bytes`, and CORS headers when its path matches `http.cors.paths`. The order is described in [Request lifecycle](../architecture/request-lifecycle.md).
|
||||
|
||||
`pact.Router.GroupRaw` declares a raw group for routes that must not be wrapped in the house JSON middleware, such as webhooks, file streams or the OAuth endpoints: the default body limit is skipped, and a panic returns a bare 500.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user