Skip to content

youaftouh/axios-cache-nats-adapter

Repository files navigation

axios-cache-nats-adapter

A NATS storage adapter for axios-cache-interceptor, enabling distributed caching using NATS JetStream Key-Value store.

Features

  • 🚀 NATS JetStream KV Store - Persistent, distributed caching
  • 📦 Dual Module Support - Works with both ESM and CommonJS
  • 🔧 Flexible Configuration - Customizable bucket, TTL, and serialization
  • 🔑 Key Prefixing - Namespace support for multiple applications
  • TypeScript - Full type safety and IntelliSense support
  • 🧪 Well Tested - Comprehensive test coverage

Installation

npm install axios-cache-nats-adapter axios-cache-interceptor nats

or

yarn add axios-cache-nats-adapter axios-cache-interceptor nats

or

pnpm add axios-cache-nats-adapter axios-cache-interceptor nats

Quick Start

ESM

import axios from 'axios';
import { setupCache } from 'axios-cache-interceptor';
import { NatsAdapter } from 'axios-cache-nats-adapter';

// Create the NATS adapter
const adapter = new NatsAdapter({
  natsOptions: {
    servers: 'nats://localhost:4222',
  },
  bucket: 'axios-cache',
  ttl: 60000, // 1 minute default TTL
});

// Setup axios with cache
const cachedAxios = setupCache(axios, {
  storage: adapter,
});

// Use it like normal axios
const response = await cachedAxios.get('https://api.example.com/data');
console.log(response.cached); // false on first request, true on subsequent

// Clean up when done
await adapter.close();

CommonJS

const axios = require('axios');
const { setupCache } = require('axios-cache-interceptor');
const { NatsAdapter } = require('axios-cache-nats-adapter');

const adapter = new NatsAdapter({
  natsOptions: {
    servers: 'nats://localhost:4222',
  },
  bucket: 'axios-cache',
});

const cachedAxios = setupCache(axios, {
  storage: adapter,
});

// Use it...

Configuration Options

NatsAdapterOptions

interface NatsAdapterOptions {
  /**
   * NATS connection options
   * @default { servers: 'nats://localhost:4222' }
   */
  natsOptions?: ConnectionOptions;

  /**
   * Name of the JetStream KV bucket to use for caching
   * @default 'axios-cache'
   */
  bucket?: string;

  /**
   * Prefix to prepend to all cache keys for namespacing
   * @default ''
   */
  keyPrefix?: string;

  /**
   * Default TTL (time-to-live) in milliseconds for cached values
   * Individual cache entries can override this
   * @default 0 (no expiration)
   */
  ttl?: number;

  /**
   * Custom serializer for encoding/decoding cached values
   * @default JsonSerializer
   */
  serializer?: Serializer;

  /**
   * Maximum number of history entries to keep in the KV bucket
   * @default 1
   */
  maxHistory?: number;

  /**
   * Whether to automatically create the KV bucket if it doesn't exist
   * @default true
   */
  autoCreateBucket?: boolean;
}

Advanced Usage

Custom Serializer

You can provide a custom serializer for advanced use cases:

import { NatsAdapter, Serializer } from 'axios-cache-nats-adapter';
import type { StorageValue } from 'axios-cache-interceptor';

class CustomSerializer implements Serializer {
  serialize(value: StorageValue): Uint8Array {
    // Your custom serialization logic
    return new TextEncoder().encode(JSON.stringify(value));
  }

  deserialize(data: Uint8Array): StorageValue {
    // Your custom deserialization logic
    return JSON.parse(new TextDecoder().decode(data));
  }
}

const adapter = new NatsAdapter({
  serializer: new CustomSerializer(),
});

Multiple Applications

Use key prefixes to isolate caches for different applications:

// Application 1
const adapter1 = new NatsAdapter({
  bucket: 'shared-cache',
  keyPrefix: 'app1:',
});

// Application 2
const adapter2 = new NatsAdapter({
  bucket: 'shared-cache',
  keyPrefix: 'app2:',
});

Per-Request TTL

You can override the default TTL per request:

const cachedAxios = setupCache(axios, {
  storage: adapter,
});

// Cache for 5 minutes
await cachedAxios.get('https://api.example.com/data', {
  cache: {
    ttl: 5 * 60 * 1000,
  },
});

Connection Management

Always clean up resources when done:

const adapter = new NatsAdapter({ /* options */ });

try {
  // Use the adapter...
} finally {
  await adapter.close();
}

Requirements

  • Node.js >= 16.0.0
  • A running NATS server with JetStream enabled

Running NATS Server

Using Docker

docker run -p 4222:4222 nats:latest -js

Using NATS CLI

nats-server -js

API Reference

NatsAdapter

Methods

  • get(key: string): Promise<StorageValue | undefined> - Get a cached value
  • set(key: string, value: StorageValue, requestConfig?: CacheProperties): Promise<void> - Set a cached value
  • remove(key: string): Promise<void> - Remove a cached value
  • find(predicate: (key: string, value: StorageValue) => boolean): Promise<StorageValue[]> - Find cached values matching a predicate
  • close(): Promise<void> - Close the NATS connection

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT © Yasser Ouaftouh

Related Projects

Support

If you encounter any issues or have questions, please open an issue on GitHub.

About

An adapter for NATS using axios-cache-interceptor

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors