Non Productive Monday

    @upstash/redis
    TypeScript icon, indicating that this package has built-in type declarations

    1.3.5 • Public • Published

    Upstash Redis

    @upstash/redis is an HTTP/REST based Redis client for typescript, built on top of Upstash REST API.

    Tests npm (scoped) npm bundle size

    It is the only connectionless (HTTP based) Redis client and designed for:

    • Serverless functions (AWS Lambda ...)
    • Cloudflare Workers (see the example)
    • Fastly Compute@Edge (see the example)
    • Next.js, Jamstack ...
    • Client side web/mobile applications
    • WebAssembly
    • and other environments where HTTP is preferred over TCP.

    See the list of APIs supported.

    Upgrading from v0.2.0?

    Please read the migration guide. For further explanation we wrote a blog post.

    Quick Start

    Install

    npm

    npm install @upstash/redis

    Deno

    import { Redis } from "https://deno.land/x/upstash_redis/mod.ts";

    Create database

    Create a new redis database on upstash

    Environments

    We support various platforms, such as nodejs, cloudflare and fastly. Platforms differ slightly when it comes to environment variables and their fetch api. Please use the correct import when deploying to special platforms.

    Node.js

    Examples: Vercel, Netlify, AWS Lambda

    If you are running on nodejs you can set UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN as environment variable and create a redis instance like this:

    import { Redis } from "@upstash/redis"
    
    const redis = new Redis({
      url: <UPSTASH_REDIS_REST_URL>,
      token: <UPSTASH_REDIS_REST_TOKEN>,
    })
    
    // or load directly from env
    const redis = Redis.fromEnv()

    Cloudflare Workers

    Cloudflare handles environment variables differently than nodejs. Please add UPSTASH_REDIS_REST_URL and UPSTASH_REDIS_REST_TOKEN using wrangler secret put ... or in the cloudflare dashboard.

    Afterwards you can create a redis instance:

    import { Redis } from "@upstash/redis/cloudflare"
    
    const redis = new Redis({
      url: <UPSTASH_REDIS_REST_URL>,
      token: <UPSTASH_REDIS_REST_TOKEN>,
    })
    
    
    // or load directly from global env
    
    // service worker
    const redis = Redis.fromEnv()
    
    
    // module worker
    export default {
      async fetch(request: Request, env: Bindings) {
        const redis = Redis.fromEnv(env)
        // ...
      }
    }

    Fastly

    Fastly introduces a concept called backend. You need to configure a backend in your fastly.toml. An example can be found here. Until the fastly api stabilizes we recommend creating an instance manually:

    import { Redis } from "@upstash/redis/fastly"
    
    const redis = new Redis({
      url: <UPSTASH_REDIS_REST_URL>,
      token: <UPSTASH_REDIS_REST_TOKEN>,
      backend: <BACKEND_NAME>,
    })

    Deno

    Examples: Deno Deploy, Netlify Edge

    import { Redis } from "https://deno.land/x/upstash_redis/mod.ts"
    
    const redis = new Redis({
      url: <UPSTASH_REDIS_REST_URL>,
      token: <UPSTASH_REDIS_REST_TOKEN>,
    })
    
    // or
    const redis = Redis.fromEnv();

    Working with types

    Most commands allow you to provide a type to make working with typescript easier.

    const data = await redis.get<MyCustomType>("key");
    // data is typed as `MyCustomType`

    Migrating to v1

    Explicit authentication

    The library is no longer automatically trying to load connection secrets from environment variables. You must either supply them yourself:

    import { Redis } from "@upstash/redis"
    
    const redis = new Redis({
      url: <UPSTASH_REDIS_REST_URL>,
      token: <UPSTASH_REDIS_REST_TOKEN>,
    })

    Or use one of the static constructors to load from environment variables:

    // Nodejs
    import { Redis } from "@upstash/redis";
    const redis = Redis.fromEnv();
    // or when deploying to cloudflare workers
    import { Redis } from "@upstash/redis/cloudflare";
    const redis = Redis.fromEnv();

    Error handling

    Errors are now thrown automatically instead of being returned to you.

    // old
    const { data, error } = await set("key", "value");
    if (error) {
      throw new Error(error);
    }
    
    // new
    const data = await redis.set("key", "value"); // error is thrown automatically

    Pipeline

    v1.0.0 introduces redis pipelines. Pipelining commands allows you to send a single http request with multiple commands.

    import { Redis } from "@upstash/redis";
    
    const redis = new Redis({
      /* auth */
    });
    
    const p = redis.pipeline();
    
    // Now you can chain multiple commands to create your pipeline:
    
    p.set("key", 2);
    p.incr("key");
    
    // or inline:
    p.hset("key2", "field", { hello: "world" }).hvals("key2");
    
    // Execute the pipeline once you are done building it:
    // `exec` returns an array where each element represents the response of a command in the pipeline.
    // You can optionally provide a type like this to get a typed response.
    const res = await p.exec<[Type1, Type2, Type3]>();

    For more information about pipelines using REST see here.

    Advanced

    A low level Command class can be imported from @upstash/redis in case you need more control about types and or (de)serialization.

    By default all objects you are storing in redis are serialized using JSON.stringify and recursively deserialized as well. Here's an example how you could customize that behaviour. Keep in mind that you need to provide a fetch polyfill if you are running on nodejs. We recommend isomorphic-fetch.

    import { Command } from "@upstash/redis/commands"
    import { HttpClient } from "@upstash/redis/http"
    
    /**
     * TData represents what the user will enter or receive,
     * TResult is the raw data returned from upstash, which may need to be
     * transformed or parsed.
     */
    const deserialize: (raw: TResult) => TData = ...
    
    class CustomGetCommand<TData, TResult> extends Command<TData | null, TResult | null> {
      constructor(key: string, ) {
        super(["get", key], { deserialize })
      }
    }
    
    const client = new HttpClient({
      baseUrl: <UPSTASH_REDIS_REST_URL>,
      headers: {
        authorization: `Bearer ${<UPSTASH_REDIS_REST_TOKEN>}`,
      },
    })
    
    const res = new CustomGetCommand("key").exec(client)

    Additional information

    keepalive

    @upstash/redis is capable of reusing connections where possible to minimize latency. Connections can be reused if the client is stored in memory and not initialized with every new function invocation. The easiest way to achieve this is by creating the client outside of your handler and adding an https agent:

    // Nextjs api route
    import { Redis } from "@upstash/redis";
    import https from "https";
    
    const redis = Redis.fromEnv({
      agent: new https.Agent({ keepAlive: true }),
    });
    
    export default async function (req, res) {
      // use redis here
    }

    Whenever your hot lambda receives a new request the client is already initialized and the previously established connection to upstash is reused.

    Javascript MAX_SAFE_INTEGER

    Javascript can not handle numbers larger than 2^53 -1 safely and would return wrong results when trying to deserialize them. In these cases the default deserializer will return them as string instead. This might cause a mismatch with your custom types.

    await redis.set("key", "101600000000150081467");
    const res = await redis<number>("get");

    In this example res will still be a string despite the type annotation. Please keep that in mind and adjust accordingly.

    Docs

    See the documentation for details.

    Contributing

    Install Deno

    Database

    Create a new redis database on upstash and copy the url and token

    Running tests

    UPSTASH_REDIS_REST_URL=".." UPSTASH_REDIS_REST_TOKEN=".." deno test -A

    Install

    npm i @upstash/redis

    DownloadsWeekly Downloads

    2,384

    Version

    1.3.5

    License

    MIT

    Unpacked Size

    371 kB

    Total Files

    377

    Last publish

    Collaborators

    • chronark
    • buggyhunter
    • upstashnpm
    • ademilter-upstash
    • mdogan