Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
August 12, 2022 05:23 am GMT

Uploading files in Remix to a S3 compatible service

Remix is a new react-based framework designed to be a full stack application. With many applications, you will need to be able to store files, sometimes in an S3 compatible service. Here is how I was able to accomplish this. I took heavy influence from this dev.to article.

Create a file named uploader-handler.server.ts with the following contents:

import { s3Client } from './s3.server';import type { UploadHandler } from '@remix-run/node';import type { PutObjectCommandInput } from '@aws-sdk/client-s3';import { GetObjectCommand } from '@aws-sdk/client-s3';import { PutObjectCommand } from '@aws-sdk/client-s3';import { getSignedUrl } from '@aws-sdk/s3-request-presigner';const uploadStreamToS3 = async (data: AsyncIterable<Uint8Array>, key: string, contentType: string) => {  const BUCKET_NAME = "my_bucket_name";  const params: PutObjectCommandInput = {    Bucket: BUCKET_NAME,    Key: key,    Body: await convertToBuffer(data),    ContentType: contentType,  };  await s3Client.send(new PutObjectCommand(params));  let url = await getSignedUrl(s3Client, new GetObjectCommand({    Bucket: BUCKET_NAME,    Key: key,  }), { expiresIn: 15 * 60 });  console.log(url);  return key;}// The UploadHandler gives us an AsyncIterable<Uint8Array>, so we need to convert that to something the aws-sdk can use. // Here, we are going to convert that to a buffer to be consumed by the aws-sdk.async function convertToBuffer(a: AsyncIterable<Uint8Array>) {  const result = [];  for await (const chunk of a) {    result.push(chunk);  }  return Buffer.concat(result);}export const s3UploaderHandler: UploadHandler = async ({ filename, data, contentType }) => {  return await uploadStreamToS3(data, filename!, contentType);}

Next, you will need to create the actual route to be able to upload a file. I have the following file: ~/routes/api/storage/upload.tsx with the following contents

import type { ActionFunction } from "@remix-run/node";import { unstable_parseMultipartFormData } from "@remix-run/node";import { auth } from "~/server/auth.server";import { s3UploaderHandler } from "~/server/uploader-handler.server";export const action: ActionFunction = async ({ request }) => {  await auth.isAuthenticated(request, { failureRedirect: '/login' });  const formData = await unstable_parseMultipartFormData(request, s3UploaderHandler);  const fileName = formData.get('upload');  return {    filename: fileName,  }}

Now that you have the supporting files in place, let's upload a file.

<Form method="post" action={'/api/storage/upload'} encType="multipart/form-data">    <Input type="file" name="upload" />    <Button type="submit">Upload</Button></Form>

There you have it!

Version of sdks used:

  • @remix-run/node: 1.6.5
  • @remix-run/react: 1.6.5
  • @aws-sdk/client-s3: 3.145.0
  • @aws-sdk/s3-request-presigner: 3.145.0

Original Link: https://dev.to/crypticai/uploading-files-in-remix-to-an-s3-compatible-service-35c9

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To