اتصال به فضای ذخیرهسازی ابری در برنامههای NextJS
برای استفاده از Object Storage در برنامههای NextJS، میتوانید از
پکیجهای aws-sdk استفاده کنید که بایستی با دستور زیر، آنها را در پروژه خود، نصب کنید:
پس از آن، کافیست تا طبق مستندات ایجاد کلید، یک کلید جدید برای باکت خود بسازید.
اطلاعات مربوط به ENDPOINT و نام باکت نیز در صفحه تنظیمات، در بخش دسترسی با SDK،
برای شما قرار گرفته است.
در نهایت نیز، بایستی
اطلاعات مربوط به Object Storage خود را
به متغیرهای محیطی برنامه خود، اضافه کنید؛ به عنوان مثال:
سپس، میتوانید در مسیر اصلی پروژه (ریشه پروژه یا اگر که از دایرکتوری src استفاده میکنید در داخل این دایرکتوری)، یک فایل جدید به نام lib/s3.ts بسازید و کد زیر را در آن قرار دهید:
کپی
// src/lib/s3.ts or /lib/s3.ts
import { S3Client } from "@aws-sdk/client-s3";
export const s3 = new S3Client({
region: "default",
endpoint: process.env.LIARA_ENDPOINT,
credentials: {
accessKeyId: process.env.LIARA_ACCESS_KEY!,
secretAccessKey: process.env.LIARA_SECRET_KEY!,
},
forcePathStyle: true,
});
تمامی کارها انجام شده است و اکنون، میتوانید APIهای مربوط به S3 را در پروژه خود، استفاده کنید. برای استفاده از APIهای مختلف S3، بایستی ساختار پروژه مانند شکل زیر باشد:
// src/app/api/storage/presigned/route.ts or /app/api/storage/presigned/route.ts
import { GetObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
import { s3 } from "@/lib/s3";
export async function POST(req: Request) {
const { key } = await req.json();
const command = new GetObjectCommand({
Bucket: process.env.LIARA_BUCKET_NAME,
Key: key,
});
const url = await getSignedUrl(s3, command, { expiresIn: 3600 });
return Response.json({ url });
}
نمونه کد دریافت لینک موقت دانلود فایل با دامنه اختصاصی
اگر طبق مستندات اتصال دامنه، یک دامنه اختصاصی به باکت خود متصل کردهاید، سادهترین روش برای دریافت لینک موقت (Presigned) با دامنه اختصاصی این است که لینک را با Endpoint اصلی لیارا تولید کنید و سپس مقدار Host آن را به دامنه اختصاصی تغییر دهید.
برای این کار، لینک باید بهصورت virtual-hosted ساخته شود؛ یعنی نام باکت در ابتدای Host قرار بگیرد (مانند bucket-name.storage.c2.liara.site) و نه در مسیر لینک. کلاینت s3 در این مستندات با forcePathStyle: true ساخته شده است و لینک را بهصورت path-style تولید میکند؛ به همین دلیل، در قطعه کد زیر یک کلاینت جداگانه بدون forcePathStyle برای ساخت لینک ایجاد شده است:
کپی
// src/app/api/storage/presigned-custom-domain/route.ts or /app/api/storage/presigned-custom-domain/route.ts
import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
const CUSTOM_DOMAIN = "example.com"; // change this to your custom domain
// without forcePathStyle, so the bucket name is placed in the host
const presignClient = new S3Client({
region: "default",
endpoint: process.env.LIARA_ENDPOINT,
requestChecksumCalculation: "WHEN_REQUIRED",
responseChecksumValidation: "WHEN_REQUIRED",
credentials: {
accessKeyId: process.env.LIARA_ACCESS_KEY!,
secretAccessKey: process.env.LIARA_SECRET_KEY!,
},
});
export async function POST(req: Request) {
const { key } = await req.json();
const signed = await getSignedUrl(
presignClient,
new GetObjectCommand({
Bucket: process.env.LIARA_BUCKET_NAME,
Key: key,
}),
{ expiresIn: 3600 }
);
const url = new URL(signed);
url.host = CUSTOM_DOMAIN;
return Response.json({ url: url.toString() });
}
فقط مقدار host را تغییر دهید و پارامترهای *-X-Amz موجود در لینک را دستکاری نکنید؛ در غیر این صورت امضای لینک نامعتبر میشود و دسترسی به فایل با خطا مواجه خواهد شد.
نمونه کد لیست کردن فایلهای داخل باکت
کپی
// src/app/api/storage/list-files/route.ts or /app/api/storage/list-files/route.ts
import { ListObjectsV2Command } from "@aws-sdk/client-s3";
import { s3 } from "@/lib/s3";
export async function GET() {
const command = new ListObjectsV2Command({
Bucket: process.env.LIARA_BUCKET_NAME,
});
const data = await s3.send(command);
return Response.json({ files: data.Contents });
}
نمونه کد لیست کردن باکتها
کپی
// src/app/api/storage/list-buckets/route.ts or /app/api/storage/list-buckets/route.ts
import { ListBucketsCommand } from "@aws-sdk/client-s3";
import { s3 } from "@/lib/s3";
export async function GET() {
const command = new ListBucketsCommand({});
const data = await s3.send(command);
return Response.json({ buckets: data.Buckets });
}
نمونه کد حذف فایل
کپی
// src/app/api/storage/delete/route.ts or /app/api/storage/delete/route.ts
import { DeleteObjectCommand } from "@aws-sdk/client-s3";
import { s3 } from "@/lib/s3";
export async function DELETE(req: Request) {
const { key } = await req.json();
const command = new DeleteObjectCommand({
Bucket: process.env.LIARA_BUCKET_NAME,
Key: key,
});
await s3.send(command);
return Response.json({ message: "File deleted" });
}
ایجاد رابط کاربری برای کار با S3
روشهای زیادی برای استفاده از S3 وجود دارد. یکی از این راهها، ایجاد رابط کاربری است که میتوان با استفاده از ابزار shadcn یک رابط کاربری زیبا و ساده ایجاد کرد. برای استفاده از این ابزار، در ابتدا، آن را با اجرای دستور زیر، نصب کنید:
کپی
npx shadcn@latest init
سپس با اجرای دستور زیر، کامپوننتهای مورد نیاز برنامه را نصب کنید:
کپی
npx shadcn@latest add button input card
در نهایت، در مسیر اصلی پروژه، یک فایل جدید به نام app/storage/page.tsx بسازید و کد زیر را در آن قرار دهید: