Blog.

Upload File AWS S3 with Node, React, Mongo (Multer S3) | Guida Italiano


Autore
Andrea Provino
Data
Tempo di lettura
5 minuti
Categoria
Guide, Portfolio

upload-file-s3-using-node-react-javascript-guida-italiano-aws-s3-caricare-file-semplice-aws-file-upload-s3

I tuoi problemi nel caricare un file su un bucket di Amazon, con il servizio AWS S3, usando un server Node e un fron-end React sono finalmente terminati: oggi ti presento la soluzione!

Quick Brief

Il nostro faraway goal è creare una piattaforma per l’acquisto e la gestione di corsi online.

Abbiamo identificato gli elementi chiave per la realizzazione del progettto, e creato un sistema per il login delgi utenti. Siamo quindi passati alla gestione delle transazioni con Stripe, e messo in secondo piano l’upload dei file.

Ora riprendiamo in mano il progetto e vediamo come gestire l’Upload file AWS S3, così da poterli facilmente visualizzare con un public url.

Project Goal

Al termine di questo progetto avremo:

  • front-end React con un semplice form per l’upload di uno o più file
  • back-end Node e MondoDB per l’upload handling e la visualizzazione dei file caricati
  • RESTful api per l’upload generico dei file e per la creazione di un prodotto da vendere

Prerequisiti

  • account AWS atttivo e funzionante
  • back-end node configurato (express, body-parser, cors, helmet, dotenv)
  • React app con router abilitato

Crezione Bucket S3

Il primo passo è accedere alla console AWS, navigare sul servizio S3 e creare un bucket: il nostro contenitore per i file.

Nel funnel di creazione dovremo prestare attenzione ad alcune cose:

  • possiamo scegliere un quasliasi nome, purché non sia già in uso presso qualche altro utente AWS.
  • dobbiamo depennare “Block all public access” allo STEP 3, in caso sarà impossibile ottenere un public URL funzionante.

Creato il bucket, prima di procedere oltre è necessario accedere alle KEY di Amazon.

In altro a destra, con un hover sul nostro nome utente si apre un dropdown contenente la voce “My Security Credential”, l’unica di nostro interesse. Clicchiamoci.

You are accessing the security credentials page for your AWS account. The account credentials provide unlimited access to your AWS resources.

Il disclaimer di AWS è sufficientemente diretto. Attento all’uso che ne fai delle credenziali che andrai a creare: condividile attentamente.

Apriamo il collapse Acces keys (acces key ID and secret access key), quindi seguiamo la procedura guidata per la creazione delle chiavi.

Andiamo quindi ad integrarle nel nostro file .env, RISPETTANDO IL NOME FORNITO:

AWS_ACCESS_KEY_ID=****
AWS_SECRET_ACCESS_KEY=****
AWS_REGION=****
S3_BUCKET=api-monolith 

Node Back-End | Handling S3 Upload File RESTfully

Abbiamo bisogno di alcuni pacchetti:

npm i aws-sdk, multer, multer-s3

Definiamo una rotta per l’upload dei file. In questo momento lavoro alle API V1, quindi quella completa sarà:

localhost:8001/V1/uploadfile
const express = require('express')
const router = express.Router()

// import controller
const ctrl = require('./utils.controller')

//define utils routes
router.route("/uploadfile")
    .post(ctrl.uploadFile) //post route

module.exports = router

All’interno del file utils.controller.js andiamo a gestire le funzioni, che saranno in grado fare l’upload su S3 con Node di file multipli.

Inziamo ad importare i pacchetti che gestiranno l’upload:

// handling mutlipart form-data
const multer = require('multer')
// avoid caching data
const multerS3 = require('multer-s3')
// aws istance (automatic config from .env file)
const AWS = require("aws-sdk")
// set s3 istances (again, automatic config from .env file)
// consider the fact that we will overwrite this configuration
const s3 = new AWS.S3()

Quindi procediamo a definire ed esportare il nostro middleware:

// at this point upload and handleUpload have to be defined
const uploadMiddleware = [upload.array("file"), handleUpload]

module.exports = {
    uploadMiddleware
}

Ora creiamo una nuova istanza di multer:

const upload = multer({
    storage: multerS3({
        s3: s3,
        bucket: 'api-monolith', // need to specify bucket
        acl: 'public-read', // set to public-read otherwise get XML file
        contentType: multerS3.AUTO_CONTENT_TYPE, // get content-type
        key: function (req, file, cb) {
            /*
            * Define the fileName
            * Can be custom, the same, or hybrid:
            */
            const fileName = (Date.now() + "-" + file.originalname)
            cb(null, fileName)
        }
    })
})

Ora la inviamo una risposta al client contenete i ref ai file appena caricati:

const handleUpload = (req, res) => {
    // get files location:
    const locations = req.files.map((item) => item.location)
    res.send({
        message: 'Successfully uploaded  files!',
        files: locations
    })
}

Et voilà backend configurato.

Si è acerbo, ma funziona!

Basterebbe implementare qualche controllo aggiuntivo e un corretto sistema di gestione degli errori. Prossimamente!

React: aws s3 form upload

Gestendo l’intero processo da back-end, il front-end si limita a passare i file binari.

Installiamo la librerie axios, per gestire agevolmente l’upload dei file :

npm i axios

Quiindi definiamo un input mutliple:

<div>
    <h1>Upload File Form</h1>
    <input multiple type="file" name="file" onChange={this.onChangeHandler} />
    <button type="button" className="btn btn-success" onClick={this.onClickHandler}>Upload</button>
</div>

E ora le funzioni:

 constructor(props) {
        super(props)
        this.state = {
            selectedFile: null
        }
    }
    onChangeHandler = (event) => {
        this.setState({
            ...this.state,
            selectedFile: event.target.files,
        })
    }
    onClickHandler = (event) => {
        const data = new FormData()
        for (var x = 0; x < this.state.selectedFile.length; x++) {
            data.append('file', this.state.selectedFile[x])
        }
        // POST url
        axios.post("http://localhost:8001/v1/uploadfile", data, { // receive two parameter endpoint url ,form data 
        })
            .then(res => { 
                // then print response status
                console.log(res.statusText)
            })
            .catch(err => {
                console.log(err)
            })
    }

Tanto margine di implementazione, ma per il momento possiamo considerarci soddisfatti!

In un futuro update, aggiungeremo il supporto a mongo DB!

Un caldo abbraccio, Andrea!

Taggedguidaportfolio projectweb development


Ultimi post

Patricia Merkle Trie

Il Practical Algorithm To Retrieve Information Coded In Alphanumeric Merkle Trie, o Patricia Merkle Trie è una struttura dati chiave-valore usatada Ethereum e particolarmente efficiente per il salvataggio e la verifica dell’integrità dell’informazione. In questo post ne studieremo le caratteristiche. Prima di procedere, ci conviene ripassare l’introduzione al Merkle Tree nella quale abbiamo chiarito il […]

Andrea Provino
ethereum-patricia-merkle-tree
Tree Data Structure: cos’è un Merkle Tree

Un Merkle Tree è una struttura dati efficiente per verificare che un dato appartenga a un insieme esteso di elementi. È comunemente impiegato nelle Peer to Peer network in cui la generazione efficiente di prove (proof) contribuisce alla scalabilità della rete. Capire i vantaggi di questa struttura ci tornerà utile nel nostro percorso di esplorazione […]

Andrea Provino
merkle-tree-cover
UTXO: come funziona il modello Unspent Transaction Outputs

Per tenere traccia dei bilanci utente, la blockchain di Bitcoin sfrutta un modello di contabilità definito UTXO o Unspent Transaction Outputs. In questo articolo ne esaminiamo le caratteristiche. Ogni blockchain è dotata di un sistema di contabilità, un meccanismo attraverso cui tenere traccia dei bilanci di ciascun utente. I due grandi modelli di riferimento nel […]

Andrea Provino
bitcoin-utxo
Cos’è Ethereum

Possiamo definire Ethereum come una macchina a stati distribuita che traccia le transizioni di un archivio dati general-purpose (i.e. una memoria in grado di registrare qualsiasi dato esprimibile come coppia di chiave e valore o key-value) all’interno della Ethereum Blockchain. È arrivato il momento di esplorare uno dei progetti tecnologici più innovativi e interessanti degli […]

Andrea Provino
ethereum