Feature Description
Support AIP-136 :verb custom methods in route paths
Gin reserves : as the path-parameter prefix, which collides with the
AIP-136 custom-method convention used by most
Google Cloud / Ads / Firebase APIs, e.g. POST /users:batchGet,
POST /v24/customers/{customer_id}:mutate.
Problem
Case A — verb after a literal segment
r := gin.New()
r.POST("/users:batchGet", h1)
r.POST("/users:batchCreate", h2) // panic: wildcard ':batchCreate' conflicts
Workable with an undocumented \: escape — gin's trie treats \: as a
literal colon, strips the backslash after registration, and FullPath()
returns the unescaped form:
r.POST(`/users\:batchGet`, h1)
r.POST(`/users\:batchCreate`, h2)
// both coexist; FullPath() -> "/users:batchGet", "/users:batchCreate"
Works in v1.12.0, but not in the README / GoDoc and has no test coverage I
could find — feels like an implementation detail that could break on a minor
release.
Case B — verb after a :param on the same segment (no workaround)
Real URL: POST /v24/customers/{customer_id}:mutate (Google Ads API).
r.POST("/customers/:customer_id:mutate", h) // gin treats everything after ':' as one param name
r.POST(`/customers/:customer_id\:mutate`, h) // the `\:` escape does NOT apply inside a param segment
Neither form expresses "param, then literal :mutate". The only option today
is to register /customers/:raw and split on : inside the handler, which
loses parameter validation and makes FullPath() useless for observability /
permission matching (every such route collapses to /customers/:raw).
Ask
Any of the following would help, in increasing effort:
- Document the
\: escape and commit to it as public API.
- First-class support: treat a colon that is not at the start of a
segment as a literal, so /users:batchGet and
/customers/:customer_id:mutate just work.
Environment
gin v1.12.0, go 1.25.4.
Feature Description
Support AIP-136
:verbcustom methods in route pathsGin reserves
:as the path-parameter prefix, which collides with theAIP-136 custom-method convention used by most
Google Cloud / Ads / Firebase APIs, e.g.
POST /users:batchGet,POST /v24/customers/{customer_id}:mutate.Problem
Case A — verb after a literal segment
Workable with an undocumented
\:escape — gin's trie treats\:as aliteral colon, strips the backslash after registration, and
FullPath()returns the unescaped form:
Works in v1.12.0, but not in the README / GoDoc and has no test coverage I
could find — feels like an implementation detail that could break on a minor
release.
Case B — verb after a
:paramon the same segment (no workaround)Real URL:
POST /v24/customers/{customer_id}:mutate(Google Ads API).Neither form expresses "param, then literal
:mutate". The only option todayis to register
/customers/:rawand split on:inside the handler, whichloses parameter validation and makes
FullPath()useless for observability /permission matching (every such route collapses to
/customers/:raw).Ask
Any of the following would help, in increasing effort:
\:escape and commit to it as public API.segment as a literal, so
/users:batchGetand/customers/:customer_id:mutatejust work.Environment
gin v1.12.0, go 1.25.4.