fastify-xstorage
getSignedUrl / getSignedUploadUrl / getPublicUrl
Generate temporary signed download URLs, presigned direct-upload URLs, or compute a synchronous public URL.
getSignedUrl / getSignedUploadUrl / getPublicUrl
Three URL helpers covering the full access spectrum:
getSignedUrl— temporary pre-signedGetObjectURL for private file downloads.getSignedUploadUrl— temporary pre-signedPutObjectURL so clients upload directly to storage without routing through your server.getPublicUrl— synchronous helper that builds the public URL by concatenatingpublicUrl+key.
Signatures
fastify.xStorage.getSignedUrl(
key: string,
expiresIn?: number, // seconds, default 3600
): Promise<string>
fastify.xStorage.getSignedUploadUrl(
key: string,
options?: SignedUploadOptions,
): Promise<SignedUploadResult>
fastify.xStorage.getPublicUrl(key: string): string // synchronous
interface SignedUploadOptions {
contentType?: string // default "application/octet-stream"
expiresIn?: number // seconds, default 3600
metadata?: Record<string, string>
}
interface SignedUploadResult {
uploadUrl: string // client PUTs to this URL
key: string
publicUrl: string // final public URL once upload completes
}
Params
getSignedUrl
| Name | Type | Required | Description |
|---|---|---|---|
key | string | Yes | Storage key of the file |
expiresIn | number | No | Expiry in seconds (default 3600) |
getSignedUploadUrl
| Name | Type | Required | Description |
|---|---|---|---|
key | string | Yes | Destination storage key for the upload |
options.contentType | string | No | Expected MIME type (default "application/octet-stream") |
options.expiresIn | number | No | Expiry in seconds (default 3600) |
options.metadata | object | No | Custom S3 metadata to attach on upload |
getPublicUrl
| Name | Type | Required | Description |
|---|---|---|---|
key | string | Yes | Storage key to build URL for |
Returns
getSignedUrl→Promise<string>— signed download URL.getSignedUploadUrl→Promise<SignedUploadResult>—{ uploadUrl, key, publicUrl }.getPublicUrl→string— synchronous, no async.
Throws
| Error | When |
|---|---|
[xStorage] key is required and must be a string | Any key arg missing or not a string |
[xStorage] expiresIn must be a positive number (seconds) | expiresIn ≤ 0 or not a number |
[xStorage] Failed to generate signed URL for "<key>": <reason> | Pre-signer error on download URL |
[xStorage] Failed to generate signed upload URL for "<key>": <reason> | Pre-signer error on upload URL |
Examples
Serve a time-limited download link for a private document
fastify.get("/documents/:id/download", { onRequest: [fastify.authenticate] }, async (request, reply) => {
const doc = await fastify.prisma.document.findUnique({
where: { id: request.params.id },
});
// 15-minute expiry
const url = await fastify.xStorage.getSignedUrl(doc.storageKey, 900);
return reply.redirect(url);
});
Client-side direct upload flow
// 1. Server: issue a presigned upload URL
fastify.post("/upload-token", async (request, reply) => {
const { filename, contentType } = request.body;
const key = `uploads/${request.user.id}/${Date.now()}-${filename}`;
const { uploadUrl, publicUrl } = await fastify.xStorage.getSignedUploadUrl(key, {
contentType,
expiresIn: 300, // 5 minutes
});
return { uploadUrl, publicUrl, key };
});
// 2. Client: PUT directly to uploadUrl with the file body
// fetch(uploadUrl, { method: "PUT", body: file, headers: { "Content-Type": contentType } })
// 3. Server: confirm key is now accessible
fastify.post("/upload-confirm", async (request, reply) => {
const { key } = request.body;
const exists = await fastify.xStorage.exists(key);
if (!exists) return reply.code(400).send({ error: "Upload not found" });
const url = fastify.xStorage.getPublicUrl(key);
return { url };
});
See Also
- download — Server-side download (routes file through your server)
- exists / getMetadata — Confirm upload completed after client PUTs
AI Context
package: "@xenterprises/fastify-xstorage"
methods: fastify.xStorage.getSignedUrl(key, expiresIn?) | fastify.xStorage.getSignedUploadUrl(key, options?) | fastify.xStorage.getPublicUrl(key)
use-when: getSignedUrl — temporary download URL (default 1h) | getSignedUploadUrl — presigned PUT URL for direct client-to-S3 uploads | getPublicUrl — synchronous public URL construction (no API call)
returns: getSignedUrl/getSignedUploadUrl → Promise<string> | getPublicUrl → string
