Documentation ¶
Overview ¶
Package ctxmeta provides a helper type for request-scoped metadata. This package is inspired by https://github.com/peterbourgon/ctxdata. (License: https://github.com/peterbourgon/ctxdata/blob/master/LICENSE) The original package doesn't support collecting different groups of contextual data. This forked version allows it.
Example (Middleware) ¶
package main import ( "fmt" "net/http" "net/http/httptest" "strings" "github.com/DoNewsCode/core/ctxmeta" ) type Server struct{} func NewServer() *Server { return &Server{} } func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { bag := ctxmeta.GetBaggage(r.Context()) bag.Set("method", r.Method) bag.Set("path", r.URL.Path) bag.Set("content_length", r.ContentLength) fmt.Fprintln(w, "OK") } type Middleware struct { next http.Handler } func NewMiddleware(next http.Handler) *Middleware { return &Middleware{next: next} } func (mw *Middleware) ServeHTTP(w http.ResponseWriter, r *http.Request) { bag, ctx := ctxmeta.Inject(r.Context()) defer func() { for _, kv := range bag.Slice() { fmt.Printf("%s: %v\n", kv.Key, kv.Val) } }() mw.next.ServeHTTP(w, r.WithContext(ctx)) } func main() { server := NewServer() middleware := NewMiddleware(server) testserver := httptest.NewServer(middleware) defer testserver.Close() http.Post(testserver.URL+"/path", "text/plain; charset=utf-8", strings.NewReader("hello world")) }
Output: method: POST path: /path content_length: 11
Index ¶
- Variables
- type Baggage
- func (b *Baggage) Delete(key interface{}) (err error)
- func (b *Baggage) Get(key string) (value interface{}, err error)
- func (b *Baggage) Map() map[string]interface{}
- func (b *Baggage) Set(key string, value interface{}) (err error)
- func (b *Baggage) Slice() []KeyVal
- func (b *Baggage) Unmarshal(path string, target interface{}) error
- func (b *Baggage) Update(key string, callback func(value interface{}) interface{}) (err error)
- type KeyVal
- type MetadataSet
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var DefaultMetadata = MetadataSet{/* contains filtered or unexported fields */}
DefaultMetadata contains the default key for Baggage in the context. Use this if there is no need to categorize metadata, ie. put all data in one baggage.
var ErrIncompatibleType = errors.New("incompatible type")
ErrIncompatibleType is returned by Unmarshal if the value associated with a key isn't assignable to the provided target.
var ErrNoBaggage = errors.New("no baggage in context")
ErrNoBaggage is returned by accessor methods when they're called on a nil pointer receiver. This typically means From was called on a context that didn't have Baggage injected into it previously via Inject.
var ErrNotFound = errors.New("key not found")
ErrNotFound is returned by Get or other accessors when the key isn't present.
Functions ¶
This section is empty.
Types ¶
type Baggage ¶
type Baggage struct {
// contains filtered or unexported fields
}
Baggage is an opaque type that can be injected into a context at e.g. the start of a request, updated with metadata over the course of the request, and then queried at the end of the request.
When a new request arrives in your program, HTTP server, etc., use the New constructor with the incoming request's context to construct a new, empty Baggage. Use the returned context for all further operations on that request. Use the From helper function to retrieve a previously-injected Baggage from a context, and set or get metadata. At the end of the request, all metadata collected will be available from any point in the callstack.
func GetBaggage ¶
GetBaggage returns the default Baggage stored in the context.
func Inject ¶
Inject constructs a Baggage object and injects it into the provided context under the default context key. Use the returned context for all further operations. The returned Data can be queried at any point for metadata collected over the life of the context.
func (*Baggage) Delete ¶
Delete key from baggage. If key doesn't exist, it returns ErrNotFound. If the MetadataSet is not associated with an initialized baggage, it returns ErrNoBaggage.
func (*Baggage) Get ¶
Get the value associated with key, or return ErrNotFound. If this method is called on a nil Baggage pointer, it returns ErrNoBaggage.
func (*Baggage) Set ¶
Set key to value. If key already exists, it will be overwritten. If this method is called on a nil Baggage pointer, it returns ErrNoBaggage.
func (*Baggage) Slice ¶
Slice returns a slice of key/value pairs in the order in which they were set.
func (*Baggage) Unmarshal ¶
Unmarshal get the value at given path, and store it into the target variable. Target must be a pointer to an assignable type. Unmarshal will return ErrNotFound if the key is not found, and ErrIncompatibleType if the found value is not assignable to target. Unmarshal also implements contract.ConfigUnmarshaler.
Example ¶
This example demonstrates how to use Unmarshal to retrieve metadata into an arbitrary type.
package main import ( "context" "fmt" "net/http" "github.com/DoNewsCode/core/ctxmeta" ) func main() { type DomainError struct { Code int Reason string } bag, _ := ctxmeta.Inject(context.Background()) derr := DomainError{Code: http.StatusTeapot, Reason: "Earl Gray exception"} bag.Set("err", derr) if target := (DomainError{}); bag.Unmarshal("err", &target) == nil { fmt.Printf("DomainError Code=%d Reason=%q\n", target.Code, target.Reason) } }
Output: DomainError Code=418 Reason="Earl Gray exception"
type KeyVal ¶
type KeyVal struct { Key string Val interface{} }
KeyVal combines a string key with its abstract value into a single tuple. It's used internally, and as a return type for Slice.
type MetadataSet ¶
type MetadataSet struct {
// contains filtered or unexported fields
}
MetadataSet is a group key to the contextual data stored the context. The data stored with different MetadataSet instances are not shared.
func New ¶
func New() *MetadataSet
New constructs a new set of metadata. This metadata can be used to retrieve a group of contextual data. The data stored with different MetadataSet instances are not shared.
func (*MetadataSet) GetBaggage ¶
func (m *MetadataSet) GetBaggage(ctx context.Context) *Baggage
GetBaggage returns the Baggage stored in the context.
func (*MetadataSet) Inject ¶
Inject constructs a Baggage object and injects it into the provided context under the context key determined the metadata instance. Use the returned context for all further operations. The returned Baggage can be queried at any point for metadata collected over the life of the context.