Skip to content

Commit

Permalink
Add support for setting metadata through context
Browse files Browse the repository at this point in the history
  • Loading branch information
Willyham committed Feb 11, 2021
1 parent 3cd56f3 commit 5999ef9
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 0 deletions.
32 changes: 32 additions & 0 deletions metadata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package typhon

import "context"

type metadataKey struct{}

// Metadata provides a transport agnostic way to pass metadata with Typhon.
// It aligns to the interface of Go's default HTTP header type for convenience.
type Metadata map[string][]string

// NewMetadata creates a metadata struct from a map of strings.
func NewMetadata(data map[string]string) Metadata {
meta := make(Metadata, len(data))
for k, v := range data {
meta[k] = []string{v}
}
return meta
}

// AppendMetadataToContext sets the metadata on the context.
func AppendMetadataToContext(ctx context.Context, md Metadata) context.Context {
return context.WithValue(ctx, metadataKey{}, md)
}

// MetadataFromContext retrieves the metadata from the context.
func MetadataFromContext(ctx context.Context) Metadata {
meta, ok := ctx.Value(metadataKey{}).(Metadata)
if !ok {
return Metadata{}
}
return meta
}
27 changes: 27 additions & 0 deletions metadata_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package typhon

import (
"context"
"testing"

"github.com/stretchr/testify/assert"
)

func TestMetadataRoundtrip(t *testing.T) {
meta := NewMetadata(map[string]string{
"meta": "data",
})
ctx := context.Background()

withMeta := AppendMetadataToContext(ctx, meta)
out := MetadataFromContext(withMeta)

assert.Equal(t, meta, out)
}

func TestMetadataNotSet(t *testing.T) {
meta := NewMetadata(map[string]string{})
out := MetadataFromContext(context.Background())

assert.Equal(t, meta, out)
}
7 changes: 7 additions & 0 deletions request.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"io"
"io/ioutil"
"net/http"
"strings"

"github.com/monzo/terrors"
)
Expand Down Expand Up @@ -175,6 +176,12 @@ func NewRequest(ctx context.Context, method, url string, body interface{}) Reque
httpReq.ContentLength = 0
httpReq.Body = &bufCloser{}
req.Request = *httpReq

// Attach any metadata in the context to the request as headers.
meta := MetadataFromContext(ctx)
for k, v := range meta {
req.Header[strings.ToLower(k)] = v
}
}
if body != nil && err == nil {
req.Encode(body)
Expand Down
13 changes: 13 additions & 0 deletions request_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package typhon

import (
"bytes"
"context"
"io/ioutil"
"strings"
"testing"
Expand Down Expand Up @@ -61,3 +62,15 @@ func TestRequestEncodeReader(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, []byte("{}\n"), body)
}

func TestRequestSetMetadata(t *testing.T) {
t.Parallel()

ctx := AppendMetadataToContext(context.Background(), NewMetadata(map[string]string{
"meta": "data",
}))

req := NewRequest(ctx, "GET", "/", nil)

assert.Equal(t, []string{"data"}, req.Request.Header["meta"])
}

0 comments on commit 5999ef9

Please sign in to comment.