Translate google.api.http to URLPattern¶
Google's google.api.http
annotation is the convention for mapping gRPC RPCs to HTTP/JSON URLs.
Vertex AI's inference RPCs, the Cloud APIs, and every service running
behind grpc-gateway
use it. The grammar is essentially URLPattern in protobuf form.
The pattern¶
service AIPlatform {
rpc Predict(PredictRequest) returns (PredictResponse) {
option (google.api.http) = {
post: "/v1/{endpoint=projects/*/locations/*/endpoints/*}:predict"
additional_bindings {
post: "/v1/{name=projects/*/locations/*/publishers/*/models/*}:predict"
}
};
}
}
{name=projects/*/locations/*/models/*} is a multi-segment capture
with a literal scaffold — exactly what URLPattern named groups do.
A Python client / proxy ingesting these URLs¶
Without a URL-pattern library, a Python proxy fronting a gRPC service that ingests these URLs writes per-endpoint regex:
import re
_PREDICT = re.compile(
r"^/v1/projects/(?P<project>[^/]+)"
r"/locations/(?P<location>[^/]+)"
r"/models/(?P<model>[^/]+):predict$"
)
def extract(path):
m = _PREDICT.match(path)
return m.groupdict() if m else None
…and a separate, similarly-shaped regex for every additional binding.
With URLPattern¶
from yarlpattern import URLPattern
PREDICT = URLPattern({
"pathname": "/v1/projects/:project/locations/:location/models/:model\\::action(predict|classify)",
})
PREDICT.exec("https://aiplatform.googleapis.com/v1/projects/p1/locations/us-central1/models/m99:predict").pathname["groups"]
# {'project': 'p1', 'location': 'us-central1', 'model': 'm99', 'action': 'predict'}
PREDICT.test("https://aiplatform.googleapis.com/v1/projects/p1/locations/us-central1/models/m99:explain")
# False — :action constraint rejects 'explain'
The \\: escapes the literal colon that separates the resource name
from the verb (Google AIP-136 convention). The :action(predict|classify)
named group enforces that only legitimate verbs match.
additional_bindings translates to a list of URLPattern objects under
one handler:
PREDICT_BINDINGS = [
URLPattern({"pathname": "/v1/projects/:project/locations/:location/endpoints/:endpoint\\:predict"}),
URLPattern({"pathname": "/v1/projects/:project/locations/:location/publishers/:publisher/models/:model\\:predict"}),
]
def route_predict(url):
for pat in PREDICT_BINDINGS:
result = pat.exec(url)
if result is not None:
return predict_handler(result.pathname["groups"])
What you get for free¶
{name=projects/*/locations/*/models/*}is URLPattern semantics in protobuf form. Translation is mechanical: each*becomes a named group; the literal scaffold (projects/,locations/,models/) stays as-is.- Verb enums via regex group.
:action(predict|classify)rejects unknown verbs at the pattern level — thegoogle.api.httpgrammar doesn't enforce this directly, but URLPattern can. additional_bindings↔ pattern list. Multiple URLPattern entries pointing at the same handler are the natural representation;compare_component()gives you the same specificity ordering grpc- gateway computes internally.- Same patterns work everywhere. A Python sidecar fronting a
gRPC-gateway-translated service, a Cloudflare Worker fronting the
same service, and a Deno trace exporter all match URLs identically
if they share the URLPattern definitions. The translation from
.prototo URLPattern is the single source of truth.