最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - File Storage (S3) with AdonisJS 5 - Stack Overflow

programmeradmin1浏览0评论

In AdonisJS v4 docs we have this section explaining how to stream files to a S3 bucket. I was looking for something similar in AdonisJS v5 docs but it have just an example of how to upload files to local server.

If it is not ready yet since Adonis 5 is not in it's last version, which is the other way to upload files to S3 though Adonis v5 (specially with typescript)?

In AdonisJS v4 docs we have this section explaining how to stream files to a S3 bucket. I was looking for something similar in AdonisJS v5 docs but it have just an example of how to upload files to local server.

If it is not ready yet since Adonis 5 is not in it's last version, which is the other way to upload files to S3 though Adonis v5 (specially with typescript)?

Share Improve this question edited Sep 22, 2020 at 2:33 tomrlh asked Aug 10, 2020 at 18:06 tomrlhtomrlh 1,0661 gold badge19 silver badges43 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 4

I've found a way to do this with aws-sdk, this code is not 100% mine:

uploadToS3Bucket function:

import * as AWS from "aws-sdk";
import { v4 as uuid } from "uuid";


const s3 = new AWS.S3({
  region: process.env.AWS_REGION,
  secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  accessKeyId: process.env.AWS_ACCESS_KEY_ID,
});

export const uploadToS3Bucket = async (
  file: any,
  bucket: string
): Promise<{ key: string; url: string }> => {
  try {
    const { type, subtype, extname } = file;
    let mimeType = type + "/" + subtype;

    let fileType = "image/jpg";

    const name = uuid() + "." + extname;

    let buffer = Buffer.from(JSON.stringify(file), "utf-8");

    await s3
      .putObject({
        Key: name,
        Bucket: bucket,
        ContentType: fileType,
        Body: buffer.toString("base64"),
        ACL: "public-read",
      })
      .promise();

    let url = `https://${bucket}.s3.amazonaws./${name}`;
    console.log(url);
    return {
      key: name,
      url,
    };
  } catch (err) {
    console.log(err);
    return err;
  }
};

And in the controller:

public async store({ request }: HttpContextContract) {
  let file = getFileFromRequest(request, "defined_file_prop_name_here");

  if (file) {
    await uploadToS3Bucket(file, BUCKET_NAME);
  }
}

Adonis 4 used flydrive to implement s3 storage, which you could also use to simplify and save time. Once configured and instantiated using flydrive is pretty simple

// Supported drivers: "local", "s3", "gcs"
await storage.disk('s3').put('testfile.txt', 'filecontents');

You can use it without ACL Permission Issue

Don't forget install S3 drive: https://docs.adonisjs./guides/drive

Example for multiple images:

import Route from '@ioc:Adonis/Core/Route'
import Drive from '@ioc:Adonis/Core/Drive'
import fs from 'fs'
import path from 'path'
import { string } from '@ioc:Adonis/Core/Helpers'

Route.post('upload', async ({ request }) => {

   const images = request.files('images')
   for (let image of images) {
      if (image !== null) {
         const slugFileName = string.camelCase(path.parse(image.clientName).name).toLowerCase();

         const fileName = `${slugFileName}.${image.extname}`
         const fileStream = fs.createReadStream(image.tmpPath!)

         await Drive.putStream(fileName, fileStream, {
            contentType: image.headers['content-type']
         })
      }
   }
})

If you want to upload a single image:

Route.post('upload', async ({ request }) => {

   const image = request.file('image')
      if (image !== null) {
         const slugFileName = string.camelCase(path.parse(image.clientName).name).toLowerCase();

         const fileName = `${slugFileName}.${image.extname}`
         const fileStream = fs.createReadStream(image.tmpPath!)

         await Drive.putStream(fileName, fileStream, {
            contentType: image.headers['content-type']
         })
      }
})
发布评论

评论列表(0)

  1. 暂无评论