HTTP Server
Expose a storage instance through a Fetch-compatible handler and connect to it with the HTTP driver.
#Create a handler
createStorageHandler returns a standard (Request) => Response fetch handler. It works with servers and runtimes that accept a Fetch API handler.
The following example uses srvx:
npm i srvximport { serve } from "srvx";
import { createStorage } from "unstorage";
import { createStorageHandler } from "unstorage/server";
import fsDriver from "unstorage/drivers/fs";
const storage = createStorage({
driver: fsDriver({ base: "./data" }),
});
const fetch = createStorageHandler(storage, {
authorize({ request, key, type }) {
const token = request.headers.get("authorization");
if (token !== `Bearer ${process.env.STORAGE_TOKEN}`) {
throw new Error(`Unauthorized ${type} for ${key}`);
}
},
});
await serve({ port: 3000, fetch });You can pass the same handler to APIs such as Bun.serve, Deno.serve, or a compatible serverless runtime.
Warning
Always authenticate and authorize requests before exposing a storage handler. The protocol supports listing, writing, deleting, and clearing data; an unprotected endpoint grants broad access to the underlying storage.
#Options
authorize(request): Runs before every supported operation. It receives{ request, key, type }, wheretypeis"read"or"write". Throw to reject the request.resolvePath(request): Overrides how the request path is converted to a storage key. It receives the FetchRequest.
Errors thrown by authorize become 401 responses unless the thrown error has a numeric status property.
#Connect with the HTTP driver
import { createStorage } from "unstorage";
import httpDriver from "unstorage/drivers/http";
const storage = createStorage({
driver: httpDriver({
base: "http://localhost:3000",
headers: {
authorization: `Bearer ${process.env.STORAGE_TOKEN}`,
},
}),
});
await storage.setItem("messages:1", { text: "Hello" });
const message = await storage.getItem("messages:1");See the HTTP driver documentation for per-request headers, raw values, and TTL options.
#Protocol
Paths map to normalized storage keys. A path ending in / or : is treated as a base for list and clear operations.
| Method | Operation | Response |
|---|---|---|
HEAD /key | hasItem(key) and getMeta(key) | 200 when found, 404 otherwise |
GET /key | getItem(key) | Serialized value, or 404 |
GET /base/ | getKeys(base) | JSON array of keys |
PUT /key | setItem(key, body) | OK |
DELETE /key | removeItem(key) | OK |
DELETE /base/ | clear(base) | OK |
For binary data:
- send
Accept: application/octet-streamwithGETto usegetItemRaw; - send
Content-Type: application/octet-streamwithPUTto usesetItemRaw.
The HTTP driver sends the ttl transaction option as an x-ttl header. When metadata contains mtime or ttl, the handler exposes it through last-modified, x-ttl, and cache-control response headers.