Documentation
¶
Overview ¶
Package transport provides a protocol-agnostic abstraction that unifies HTTP and gRPC request/response metadata. Middleware and business logic depend only on the Transporter interface, never on the concrete protocol, so the same code serves both transports.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewServerContext ¶
func NewServerContext(ctx context.Context, tr Transporter) context.Context
NewServerContext returns a new context with tr attached.
func Release ¶
func Release(t Transporter)
Release returns a Transporter obtained from NewTransporter to the pool, clearing its fields so pooled instances do not retain request-scoped references. It must only be called after all readers of the Transporter (for example, middlewares that extract it from the context) have finished.
Types ¶
type Header ¶
type Header interface {
// Get returns the first value for key, or "" when absent.
Get(key string) string
// Set replaces the value for key with a single value.
Set(key, value string)
// Add appends value to key.
Add(key, value string)
// Keys returns all present header keys.
Keys() []string
// Values returns all values for key.
Values(key string) []string
}
Header is a protocol-agnostic view over request/response headers. It is satisfied by both http.Header and grpc metadata.MD through the adapters below, so middleware can read and write headers without knowing the transport.
func NewHTTPHeader ¶
NewHTTPHeader wraps an http.Header as a Header.
func NewMetadataHeader ¶
NewMetadataHeader wraps a grpc metadata.MD as a Header.
type Option ¶ added in v0.0.5
type Option func(*transporter)
Option fills in the protocol-specific request metadata a Transporter carries in addition to its generic parts.
func WithHTTPRequest ¶ added in v0.0.5
WithHTTPRequest records what only the HTTP bridge knows: the verb, the route template the router matched, the raw path and the protocol version. Passing route as "" is meaningful — it is how an unmatched request (a 404, a scanner) is reported under the bounded "METHOD unmatched" operation instead of under its own path.
type Transporter ¶
type Transporter interface {
// Kind returns the transport protocol of this request.
Kind() Kind
// Operation returns the fully-qualified operation name. For gRPC this is
// the full method name (e.g. "/edu.course.student-api.StudentService/Create");
// for HTTP it is "METHOD /route/template" (e.g. "POST /v1/users/:userID"),
// or "METHOD unmatched" when no route matched.
//
// It is deliberately the *route template* and not the request path. This
// string is a metric label and a span name, and a path carrying a path
// parameter — "/v1/users/usr-123" — is one series per user, which is how a
// single label grows without bound until the metrics backend it feeds stops
// answering. The raw path is still available, as Path, for the span only.
Operation() string
// Endpoint returns the address of the server handling this request.
Endpoint() string
// RequestHeader returns the incoming request headers.
RequestHeader() Header
// ReplyHeader returns the outgoing response headers.
ReplyHeader() Header
// Method returns the HTTP verb, or "" when the transport is not HTTP. With
// Route it forms the low-cardinality pair the HTTP semantic conventions
// report a request under (http.request.method + http.route).
Method() string
// Route returns the matched route template in the framework's own syntax
// ("/v1/users/:userID"), or "" when the transport has no routing (gRPC) or
// nothing matched. It is what Operation renders, minus the verb.
Route() string
// Path returns the raw request path, or "" when the transport is not HTTP.
// It belongs on the span (url.path) and never on a metric.
Path() string
// Protocol returns the protocol version as it appears in
// network.protocol.version ("1.1", "2.0"), or "" when unknown.
Protocol() string
// StatusCode returns the HTTP response status, or 0 when the transport is
// not HTTP or the response has not been written yet.
StatusCode() int
// SetStatusCode records the HTTP response status. The bridge calls it once
// the response is final and before the middleware chain unwinds, so every
// middleware above the handler observes the same value.
SetStatusCode(int)
// GRPCCode returns the gRPC status of the call: codes.OK when it succeeded
// and when the transport is not gRPC.
GRPCCode() codes.Code
// SetGRPCCode records the gRPC status, on the same "before the chain
// unwinds" terms as SetStatusCode.
SetGRPCCode(codes.Code)
}
Transporter carries the protocol-agnostic metadata of an in-flight request. It flattens http.Header and grpc metadata.MD behind a single Header interface, following the kratos transport abstraction.
func FromServerContext ¶
func FromServerContext(ctx context.Context) (Transporter, bool)
FromServerContext extracts a Transporter previously attached via NewServerContext. The bool is false when no Transporter is present.
func NewTransporter ¶
func NewTransporter(kind Kind, operation, endpoint string, reqHeader, replyHeader Header, opts ...Option) Transporter
NewTransporter builds a Transporter from its component parts, obtaining the backing struct from a pool. Callers that take the hot request path should defer transport.Release(t) once the chain has finished reading it.
The gRPC and HTTP claims about a request are not the same shape, so the protocol-specific half arrives through opts rather than as more positional arguments that one of the two callers would always leave empty.