httpcache

package module
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Nov 23, 2022 License: Apache-2.0 Imports: 11 Imported by: 0

README

httpcache

A simple net/http client cache for Go that caches responses in your chosen cache backend.

Tests

Features:

  • Configurable cache keys
  • Configurable TTL
  • Configurable caching check to decide if a response should be cached
  • Configurable cache backends
  • Configurable compression
  • Memory only cache backend
  • Redis Cache backend, with support for multi-tiered caching
  • RFC 7234 support (PRs welcome)

Installation

go get ivan.dev/httpcache

Usage

// Create a new cache using Redis Cache
myCache := cache.New(&cache.Options{Redis: redisClient})

// Setup transport (using tripware)
transport := tripware.New(http.DefaultTransport)
transport.Use(httpcache.WithCache(myCache, 1*time.Minute))
client := &http.Client{Transport: transport}

// Alternative setup transport using http.RoundTripper
// You can use other cache implementations with this approach
transport := httpcache.NewCacheTransport(http.DefaultTransport, httpcache.RedisCache(myCache), 1*time.Minute)
client := &http.Client{Transport: transport}

See simple GET example for a runnable example.

You can inspect a response to see if it was returned from the cache using httpcache.IsCachedResponse(resp) or checking the value of the X-HTTP-Cache header.

Configuration

WithTTL(time.Duration)

Sets the default TTL (Time-To-Live) for each cached request, if the underlying cache implementation supports per-item TTLs. If you're using the default RedisCache implementation, then this value will be used, however, if you're using the TinyLFU implementation, the TTL will be configured by TinyLFU

WithRequestChecker(...)
WithRequestChecker(func(req *http.Request) bool{
  return req.Method == http.MethodGet
})

A function that checks if the current request is cacheable.

Default: All GET and HEAD requests that DO NOT specify a range header.

WithCacheKeyFn(...)

Specifies the function to generate cache keys if the current solution doesn't meet your requirements.

Default implementation looks like this and produces keys like "httpcache:GET:89dce6a446a69d6b9bdc01ac75251e4c322bcdff"

WithCacheKeyFn(func(req *http.Request) string{
  urlString := req.URL.String()
  return fmt.Sprintf("%s:%s:%x", cacheKeyPredix, req.Method, sha1.Sum([]byte(urlString)))
})
WithCompression()

Enables extra GZIP compression of each response. This usually ins't necessary since with Redis Cache because it has its own S2 based caching if it decides that it is needed.

Use this if the cache implementation doesn't support compression and you need it.

Why this exists

Two reasons:

  1. You need a http client that respects cache headers and doesn't request cached assets multiple times.
  2. You want to cache API responses at a low level so that your application code doesn't abuse the upstream API.

Both these use cases are not supported out of the box with http.Client in the Go standard library.

Documentation

Index

Constants

View Source
const HTTPCacheHeader = "X-Http-Cache"

Variables

This section is empty.

Functions

func CacheKey

func CacheKey(req *http.Request) string

func DefaultRequestChecker

func DefaultRequestChecker(req *http.Request) bool

func IsCachedResponse

func IsCachedResponse(resp *http.Response) bool

func WithCache

func WithCache(c *cache.Cache, opts ...Option) tripware.Tripperware

WithCache returns a http.Client tripware that will cache responses. Use with tripware pkg.

Types

type Cache

type Cache interface {
	Set(ctx context.Context, key string, data []byte, ttl time.Duration) error
	Get(ctx context.Context, key string) ([]byte, error)
	Del(ctx context.Context, key string) error
}

func MemoryCache added in v0.1.0

func MemoryCache(size int, ttl time.Duration) Cache

MemoryCache is a simple in-memory cache using an LFU cache.

func RedisCache

func RedisCache(cache *cache.Cache) Cache

RedisCache is a cache implementation using Redis Cache. It can be constructed with an LFU cache to do memory hits before hitting Redis.

type Option

type Option func(*Transport)

func WithCacheKeyFn

func WithCacheKeyFn(fn func(req *http.Request) string) Option

WithCacheKeyFn returns a new RoundTripper that will use a custom function to generate cache keys

func WithCompression added in v0.1.0

func WithCompression() Option

func WithRequestChecker

func WithRequestChecker(check func(req *http.Request) bool) Option

WithRequestChecker returns a new RoundTripper that will check if a request should be cached

func WithTTL

func WithTTL(ttl time.Duration) Option

WithCache returns a new RoundTripper that will cache responses

type Transport

type Transport struct {
	// The RoundTripper interface actually used to make requests
	// If nil, http.DefaultTransport is used
	Cache Cache
	// contains filtered or unexported fields
}

Transport is an implementation of http.RoundTripper that will return values from a cache where possible (avoiding a network request) and will additionally add validators (etag/if-modified-since) to repeated requests allowing servers to return 304 / Not Modified

func NewCacheTransport

func NewCacheTransport(next http.RoundTripper, c Cache, options ...Option) *Transport

func (*Transport) RoundTrip

func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip implements the RoundTripper interface

Directories

Path Synopsis
examples
simple-get command

Jump to

Keyboard shortcuts

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