Skip to content

Support Google AIP-136 :verb custom methods in route paths #4641

@revisegoal

Description

@revisegoal

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:

  1. Document the \: escape and commit to it as public API.
  2. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    type/proposalGot an idea for a feature that Gin doesn't have currently? Submit your idea here!

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions