protobuf

package module
v1.5.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 29, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Overview

Package protobuf provides Protocol Buffers serialization for celeris.

Protocol Buffers support was split from the celeris core to avoid pulling google.golang.org/protobuf as a transitive dependency. This package provides equivalent functionality as standalone helpers and an optional middleware.

Key exports:

  • Write — marshal a proto.Message and write it with status code.
  • BindProtoBuf — read the request body and unmarshal it as protobuf.
  • Bind — like BindProtoBuf but first checks the Content-Type header, returning ErrNotProtoBuf when it is not a protobuf content type.
  • Respond — content-negotiate between protobuf and JSON using the Accept header, honoring q=0 exclusions per RFC 7231 §5.3.1.
  • New / Config — optional middleware that stashes marshal/unmarshal options in the request context for retrieval via FromContext.
  • PoolEvictions — monotonic counter for buffers discarded from the internal marshal pool; wire into metrics to detect large messages.

Both "application/x-protobuf" (ContentType) and "application/protobuf" (ContentTypeAlt) are accepted on inbound requests. Responses written by Write always use "application/x-protobuf".

Documentation

Full guides and examples: https://goceleris.dev/docs/middleware-content

Index

Examples

Constants

View Source
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

View Source
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.

View Source
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

func Bind(c *celeris.Context, v proto.Message) error

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

func BindProtoBuf(c *celeris.Context, v proto.Message) error

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

func Respond(c *celeris.Context, code int, v proto.Message, jsonFallback any) error

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

func Write

func Write(c *celeris.Context, code int, v proto.Message) error

Write serializes v as Protocol Buffers and writes it with the given status code and content type "application/x-protobuf".

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

func FromContext(c *celeris.Context) *Helper

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

func (h *Helper) Bind(v proto.Message) error

Bind reads the request body and unmarshals it using the stored Config.UnmarshalOptions. Returns ErrNotProtoBuf if the content type is not protobuf.

func (*Helper) Write

func (h *Helper) Write(code int, v proto.Message) error

Write serializes v as protobuf using the stored Config.MarshalOptions.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL