nico.fyi
    Published on

    Async Local Storage in Node.js

    Authors
    • avatar
      Name
      Nico Prananta
      Twitter
      @2co_p

    Recently, a developer's tweet sparked a debate about Next.js's approach to simplifying its API, particularly regarding the headers and cookies functions. This tweet resonated with a significant number of developers who favored having the request object universally accessible.

    Personally, I find myself agreeing with these viewpoints to some extent. However, the convenience offered by these functions cannot be overlooked. This led me to delve into how the headers and cookies functions are actually implemented in Next.js. Thanks to the open-source nature of the Next.js repository, I was able to locate the implementation of the headers function. The key here seems to be the use of AsyncLocalStorage.

    Async Local Storage, in essence, is Node.js's counterpart to React's Context. It allows data to be stored and retrieved from any point within the execution context, eliminating the need to pass arguments from one function to another.

    This example will show how to set and retrieve a value within the same asynchronous context.

    const { AsyncLocalStorage } = require('async_hooks')
    const asyncLocalStorage = new AsyncLocalStorage()
    

    Next, use the run method to establish a new asynchronous context. Within this context, you can set and retrieve values using the storage.

    asyncLocalStorage.run(new Map(), () => {
      // Set a value in the storage
      asyncLocalStorage.getStore().set('key', 'value')
    
      // Retrieve the value later in the same asynchronous context
      const value = asyncLocalStorage.getStore().get('key')
      console.log(value) // Output: 'value'
    })
    

    I haven't tried but it seems to be possible to use Async Local Storage in Next.js for example to make the request object available in every functions called within an API handler.


    By the way, I'm making a book about Pull Requests Best Practices. Check it out!