Documentation
¶
Overview ¶
Package protobuf provides Protocol Buffers serialization for celeris.
Protocol Buffers was removed from the celeris core to avoid forcing google.golang.org/protobuf as a transitive dependency. This package provides equivalent functionality as standalone functions.
Basic Usage ¶
Write a protobuf response:
protobuf.Write(c, 200, &myProto)
Parse a protobuf request:
var msg pb.MyMessage
if err := protobuf.BindProtoBuf(c, &msg); err != nil {
return err
}
Auto-detect content type:
var msg pb.MyMessage
if err := protobuf.Bind(c, &msg); err != nil {
return err
}
Content Negotiation ¶
Use Respond to serve protobuf or JSON based on the Accept header:
protobuf.Respond(c, 200, &myProto, myJSONStruct)
Middleware with Custom Options ¶
Install the middleware for custom marshal/unmarshal options:
s.Use(protobuf.New(protobuf.Config{
MarshalOptions: proto.MarshalOptions{Deterministic: true},
}))
Then use FromContext in handlers:
pb := protobuf.FromContext(c) pb.Write(200, &myProto)
Content Types ¶
Both "application/x-protobuf" (primary) and "application/protobuf" are recognized. Responses use "application/x-protobuf".
Index ¶
- Constants
- Variables
- func Bind(c *celeris.Context, v proto.Message) error
- func BindProtoBuf(c *celeris.Context, v proto.Message) error
- func New(config ...Config) celeris.HandlerFunc
- func Respond(c *celeris.Context, code int, v proto.Message, jsonFallback any) error
- func Write(c *celeris.Context, code int, v proto.Message) error
- type Config
- type Helper
Examples ¶
Constants ¶
const ( // ContentType is the primary MIME type for protobuf payloads. ContentType = "application/x-protobuf" // ContentTypeAlt is an alternative MIME type accepted for compatibility. ContentTypeAlt = "application/protobuf" )
Content type constants for Protocol Buffers.
Variables ¶
var ( // ErrNilMessage is returned when a nil proto.Message is passed to ProtoBuf. ErrNilMessage = errors.New("protobuf: nil proto.Message") // ErrInvalidProtoBuf is returned when unmarshaling fails. ErrInvalidProtoBuf = errors.New("protobuf: invalid protobuf data") // ErrNotProtoBuf is returned by Bind when the content type is not protobuf. ErrNotProtoBuf = errors.New("protobuf: content type is not protobuf") )
Sentinel errors.
var PoolEvictions atomic.Uint64
PoolEvictions counts how many times a marshal buffer exceeded maxPooledBufSize and was discarded instead of returned to the pool. Monotonically increasing; safe for concurrent reads.
Functions ¶
func Bind ¶
Bind reads the request body and unmarshals it into v, but only if the Content-Type header indicates protobuf (application/x-protobuf or application/protobuf). Returns ErrNotProtoBuf if the content type does not match.
func BindProtoBuf ¶
BindProtoBuf reads the request body and unmarshals it into v as Protocol Buffers. Returns celeris.ErrEmptyBody if the body is empty.
func New ¶
func New(config ...Config) celeris.HandlerFunc
New creates a middleware that stores protobuf Config in the request context for later retrieval via FromContext. This enables route handlers to use custom marshal/unmarshal options without passing them explicitly.
Example ¶
Install the middleware to add a c.Get("protobuf.config") helper that other middleware (e.g. logger) can use to detect protobuf responses.
package main
import (
"fmt"
"google.golang.org/protobuf/types/known/wrapperspb"
"github.com/goceleris/celeris"
"github.com/goceleris/celeris/middleware/protobuf"
)
func main() {
s := celeris.New(celeris.Config{})
s.Use(protobuf.New())
s.POST("/echo", func(c *celeris.Context) error {
var in wrapperspb.StringValue
if err := protobuf.BindProtoBuf(c, &in); err != nil {
return celeris.NewHTTPError(400, "invalid protobuf body")
}
return protobuf.Write(c, 200, &in)
})
fmt.Println("ok")
}
Output: ok
func Respond ¶
Respond performs content negotiation between protobuf and JSON. If the client accepts protobuf (via Accept header), v is serialized as protobuf. Otherwise, jsonFallback is serialized as JSON.
The Content-Type written is the exact variant the client prefers (application/x-protobuf vs application/protobuf), honoring q=0 to exclude either form per RFC 7231 §5.3.1.
Example ¶
Use Respond when you want a single handler to serve protobuf to protobuf-aware clients and JSON to everyone else. The Accept header is parsed for q-values and the highest-ranked match wins.
package main
import (
"fmt"
"google.golang.org/protobuf/types/known/wrapperspb"
"github.com/goceleris/celeris"
"github.com/goceleris/celeris/middleware/protobuf"
)
func main() {
s := celeris.New(celeris.Config{})
s.GET("/profile", func(c *celeris.Context) error {
// Protobuf message; JSON fallback uses the same data via map.
msg := wrapperspb.String("alice")
jsonFallback := map[string]string{"name": "alice"}
return protobuf.Respond(c, 200, msg, jsonFallback)
})
fmt.Println("ok")
}
Output: ok
Types ¶
type Config ¶
type Config struct {
// MarshalOptions controls proto marshaling behavior.
// Default: proto.MarshalOptions{} (non-deterministic for performance).
MarshalOptions proto.MarshalOptions
// UnmarshalOptions controls proto unmarshaling behavior.
// Default: proto.UnmarshalOptions{DiscardUnknown: true} (safe default).
UnmarshalOptions proto.UnmarshalOptions
}
Config controls protobuf marshaling and unmarshaling options.
type Helper ¶
type Helper struct {
// contains filtered or unexported fields
}
Helper provides protobuf operations using the Config stored by the New middleware.
func FromContext ¶
FromContext returns a Helper using the config stored by the New middleware. If the middleware was not installed, returns a Helper with default options.
func (*Helper) Bind ¶
Bind reads the request body and unmarshals it using the stored [Config.UnmarshalOptions]. Returns ErrNotProtoBuf if the content type is not protobuf.