Documentation
¶
Overview ¶
Package codec provides content-type-aware message marshalers for the HTTP transport, supporting JSON and Protobuf bodies.
Index ¶
- Constants
- func Bind(c *gin.Context, msg proto.Message) error
- func BindHTTP(c *gin.Context, msg proto.Message, template, body string) error
- func BindPath(c *gin.Context, msg proto.Message, template string) error
- func BindQuery(c *gin.Context, msg proto.Message) error
- func BuildPath(template string, msg proto.Message) (string, error)
- func Render(c *gin.Context, status int, v any)
- func RenderError(c *gin.Context, err error)
- type JSON
- type Marshaler
- type Proto
- type ProtoJSON
Constants ¶
const ( ContentTypeJSON = "application/json" ContentTypeProto = "application/x-protobuf" )
Content types understood by the codec package.
Variables ¶
This section is empty.
Functions ¶
func Bind ¶
Bind reads the request body and unmarshals it into a protobuf message using the codec selected by the request Content-Type. Unknown or empty content types fall back to JSON.
req := &pb.HelloRequest{}
if err := codec.Bind(c, req); err != nil { ... }
func BindHTTP ¶
BindHTTP decodes a protobuf request message from the full HTTP surface in one place: path parameters (from the "{field}" placeholders in template), query parameters, and the request body when body == "*". It is the single binding entry point behind server.Method.httpHandler, replacing the per-method hand-written BindPath/BindQuery/Bind sequences that generated code used to emit.
func BindPath ¶
BindPath populates msg from the path parameters declared by template. A template placeholder "{name}" maps to the request message field "name" (via gin's c.Param("name")). Path values are strings; scalar fields are coerced using the same rules as BindQuery. Unknown placeholders are ignored so a single template may carry multiple parameters.
func BindQuery ¶
BindQuery populates msg from the URL query parameters. Each query key names a request message field (snake_case or lowerCamelCase); values are coerced to the field's scalar type, enum name, repeated scalar, or a nested message field keyed by dot ("a.b=1"). Unknown query keys are ignored.
func BuildPath ¶
BuildPath substitutes the "{field}" placeholders in template with the string form of the matching scalar fields on msg, returning the concrete URL path. It is the client-side inverse of BindPath: where BindPath decodes a path into the message, BuildPath encodes the message back into the path. An unset field renders as the empty string; an unknown placeholder is left verbatim.
func Render ¶
Render marshals v using the codec selected by the Accept header and writes it with the matching Content-Type. Unknown or empty Accept falls back to JSON. On a marshal error it aborts with HTTP 500.
codec.Render(c, http.StatusOK, &pb.HelloReply{Message: "hi"})
func RenderError ¶
RenderError normalizes an arbitrary error into an *errorsx.ErrorX and writes it as a JSON envelope carrying its code/reason/message/metadata fields, with the matching HTTP status code. Error responses are always JSON: the gRPC transport carries the same error through GRPCStatus(), so a service returns one error and both protocols render it consistently.
Types ¶
type JSON ¶
type JSON struct{}
JSON is the application/json codec, backed by encoding/json.
This is not the codec a protobuf client wants ¶
For a value that implements proto.Message this codec is wrong in both directions, and wrong *late*: encoding/json and protobuf-JSON disagree about every well-known type. A google.protobuf.Timestamp is an RFC3339 string on the wire and a {Seconds, Nanos} struct in Go, so decoding one fails on the first message that actually carries a date —
json: cannot unmarshal string into Go struct field Membership.membership.createdAt of type timestamppb.Timestamp
— while an unset timestamp is `null` and decodes cleanly. A client that works against empty data and breaks on real data is the worst shape a defect has. Duration ("1.5s"), FieldMask, Struct/Value and the wrapper types have the same problem, and marshalling goes the other way: protojson servers do not accept {"seconds":…} for a timestamp.
A client that talks to a protobuf server should use ProtoJSON instead. This codec stays the default for the server's own request binding, where it has been in use across every route and where the contract's request messages carry no well-known types — changing that default would alter the accepted wire format of 284 endpoints to fix a client-side defect. See docs/fix.md.
type Marshaler ¶
type Marshaler interface {
ContentType() string
Marshal(v any) ([]byte, error)
Unmarshal(data []byte, v any) error
}
Marshaler marshals and unmarshals a message body and reports its content type.
func FromAccept ¶
FromAccept returns the codec matching an Accept header value, defaulting to JSON when it does not request protobuf.
func FromContentType ¶
FromContentType returns the codec matching a request Content-Type header, defaulting to JSON for unknown or empty types.
type Proto ¶
type Proto struct{}
Proto is the application/x-protobuf codec.
func (Proto) ContentType ¶
ContentType returns application/x-protobuf.
type ProtoJSON ¶
type ProtoJSON struct{}
ProtoJSON is the application/json codec backed by protojson.
It is the codec for talking to a service whose messages are protobuf: the wire format is protobuf-JSON, and this is the decoder that reads it. Use it for any protobuf request or response — see JSON for what goes wrong otherwise.
It reads this platform's responses, which protojson would not write ¶
protojson's parser accepts more than its writer emits, and one of the differences is load-bearing here: the contract types 64-bit integers as JSON numbers (see internal/pkg/rest.Marshal), where protojson writes them as quoted strings. protojson parses both forms, so a client using this codec reads `"price":399` and `"price":"399"` alike.
Unknown fields are rejected, matching protojson's default. That is the right default for a typed client: a field the server sends and the client's IDL does not know is a version skew worth reporting, not something to drop.
func (ProtoJSON) ContentType ¶
ContentType returns application/json: this is a JSON encoding of a protobuf message, not the binary format.