AWS JavaScript SDK
This guide assumes that you have followed the steps in the Getting Started guide, and have the access keys available.
You may continue to use the AWS JS SDK as you normally would, but with the
endpoint set to https://fly.storage.tigris.dev
. Also make sure that
s3ForcePathStyle
is set to false
.
import { S3Client } from "@aws-sdk/client-s3";
const S3 = new S3Client({
region: "auto",
endpoint: "https://fly.storage.tigris.dev",
s3ForcePathStyle: false,
});
Getting started
This example uses the
AWS Node.js SDK v3 and reads
the default credentials file or the environment variables AWS_ACCESS_KEY_ID
and AWS_SECRET_ACCESS_KEY
.
import {
S3Client,
paginateListBuckets,
paginateListObjectsV2,
PutObjectCommand,
} from "@aws-sdk/client-s3";
import { readFile } from "node:fs/promises";
// listBuckets returns a list of all S3 buckets in the account with
// metadata such as creation date and owner.
export const listBuckets = async (S3) => {
const buckets = [];
for await (const page of paginateListBuckets({ client: S3 }, {})) {
if (page.Buckets) {
buckets.push(...page.Buckets);
}
}
return buckets;
};
// listObjects returns a list of all objects in a bucket. This only returns
// the keys of the objects, not the objects themselves. Customize the
// objects.push line to return more metadata about the objects.
export const listObjects = async (S3, bucketName) => {
const paginator = paginateListObjectsV2(
{ client: S3, pageSize: 100 },
{ Bucket: bucketName }
);
const objects = [];
for await (const page of paginator) {
if (page.Contents) {
objects.push(page.Contents.map((o) => o.Key)); // only get object keys
}
}
return objects;
};
// uploadObjectFromFS uploads a file from the local filesystem to an S3 bucket.
// This does not handle large files or multipart uploads.
export const uploadObjectFromFS = async (S3, bucket, key, filePath) => {
const command = new PutObjectCommand({
Bucket: bucket,
Key: key,
Body: await readFile(filePath),
});
const response = await S3.send(command);
return response;
};
const S3 = new S3Client({
region: "auto",
s3ForcePathStyle: false,
});
console.log("List buckets");
const buckets = await listBuckets(S3);
console.log("Buckets:", buckets);
console.log("List objects in a bucket");
const objects = await listObjects(S3, "tigris-example");
objects.forEach((objects, pageNum) => {
console.log(`Page ${pageNum + 1}:`, objects);
});
console.log("Upload an object");
const response = await uploadObjectFromFS(
S3,
"tigris-example",
"examples/js/getting-started.js",
"getting-started.js"
);
console.log("Upload response:", response);
Using presigned URLs
Presigned URLs can be used with the AWS Node.js SDK as follows:
import {
S3Client,
GetObjectCommand,
PutObjectCommand,
DeleteObjectCommand,
} from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
const S3 = new S3Client({
region: "auto",
s3ForcePathStyle: false,
});
// Presigned GET, allows users to download objects without making the bucket public.
console.log(
"GET:",
await getSignedUrl(
S3,
new GetObjectCommand({ Bucket: "tigris-example", Key: "bar.txt" }),
{ expiresIn: 3600 } // 1 hour
)
);
// Presigned PUT, allows users to upload objects without going through your server.
console.log(
"PUT:",
await getSignedUrl(
S3,
new PutObjectCommand({ Bucket: "tigris-example", Key: "bar.txt" }),
{ expiresIn: 3600 } // 1 hour
)
);
// Presigned DELETE, allows users to delete objects.
console.log(
"DELETE:",
await getSignedUrl(
S3,
new DeleteObjectCommand({ Bucket: "tigris-example", Key: "bar.txt" }),
{ expiresIn: 3600 } // 1 hour
)
);
You can now use the URL returned by the getSignedUrl
function to download or
upload objects to the bucket using the https
package.
Renaming objects
Objects can be renamed in Tigris by attaching
the X-Tigris-Rename
header to a CopyObject request.
import {
S3Client,
PutObjectCommand,
CopyObjectCommand,
DeleteObjectCommand,
HeadObjectCommand,
} from "@aws-sdk/client-s3";
import { randomUUID } from "node:crypto";
export const renameObject = async (S3, bucket, oldKey, newKey) => {
S3.middlewareStack.add(
(next) => async (args) => {
// eslint-disable-next-line no-param-reassign
args.request.headers["X-Tigris-Rename"] = "true";
return next(args);
},
{
step: "build",
name: "renameObject",
tags: ["METADATA", "RENAME"],
}
);
const copyCommand = new CopyObjectCommand({
Bucket: bucket,
CopySource: `${bucket}/${oldKey}`,
Key: newKey,
});
await S3.send(copyCommand);
S3.middlewareStack.remove("renameObject");
};
const S3 = new S3Client({
region: "auto",
s3ForcePathStyle: false,
endpoint: "https://fly.storage.tigris.dev",
});
const bucket = "tigris-example";
const object = randomUUID();
const newObject = randomUUID();
let command = new PutObjectCommand({
Bucket: bucket,
Key: object,
Body: "Hello, Tigris!",
});
await S3.send(command);
console.log("Rename object");
await renameObject(S3, bucket, object, newObject);
command = new HeadObjectCommand({
Bucket: bucket,
Key: newObject,
});
await S3.send(command);
command = new DeleteObjectCommand({
Bucket: bucket,
Key: newObject,
});
await S3.send(command);