/gcache

grpc caching interceptors

Primary LanguageGoMIT LicenseMIT

gcache Go Reference Go codecov

gcache uses a plain old ETag, If-None-Match (as defined in RFC7232), Cache-Control headers to control the caching of responses.

The standard is mostly used in caching the static files, but it can be used in caching the dynamic content as well.

Briefly, the key idea is that the gRPC service responds to the client with the ETag header in metadata, client caches the response with this ETag, sends the request to the service with that ETag of the cached response, and, if the service has detected that the resource hasn't changed (judging by the provided ETag), responds the client with codes.Aborted and the provided ETag (similar with 304 Not Modified status code).

The package also provides a server-side cache, it looks only for a client's Cache-Control header, if it is set to no-cache, the server doesn't send the cached response and evaluates the response as usual.

Installation

go get -u github.com/cappuccinotm/gcache

Usage

Client-side caching

icptr := gcache.NewInterceptor(gcache.WithLogger(slog.Default()))
conn, err := grpc.NewClient("localhost:8080",
    grpc.WithTransportCredentials(insecure.NewCredentials()),
    grpc.WithUnaryInterceptor(icptr.UnaryClientInterceptor()),
)
if err != nil {
    return fmt.Errorf("dial localhost:8080: %w", err)
}

client := order.NewOrderServiceClient(conn)

Client-side interceptor seeks for server's ETag header in the response, if the server has provided one, it stores the response in the cache. When the client sends a request, the interceptor adds the If-None-Match header to the request. If the server responds with code Aborted and the ETag header, equal to the one that has been sent by client, the interceptor returns the cached response.

Server-side caching

icptr := gcache.NewInterceptor(gcache.WithLogger(slog.Default()))
server := grpc.NewServer(
    grpc.WithTransportCredentials(insecure.NewCredentials()),
    grpc.WithUnaryInterceptor(icptr.UnaryServerInterceptor()),
)

Server-side interceptor always sends the cached response unless client has specifically set the Cache-Control: no-cache header.