Using DigitalOcean Spaces with AWS S3 SDKs and Nodejs24 September 2020Programing

Using DigitalOcean Spaces with AWS S3 SDKs and Nodejs

วันนี้จะมานำเสนอการอัพโหลดไฟล์ไป Space ของ DigitalOcean โดยการใช้งาน Nodejs ซึ่งมีเพียงไม่กี่ขั้นตอนและเพื่อนๆ สามารถนำไปประยุกต์ใช้การงานของตัวเองได้เลย

ก่อนจะลงมืออยากให้เตรียม Tools ที่จะใช้งานซึ่งประกอบไปด้วย

  1. Account DigitalOcean ที่เราจะไปสร้าง space
  2. 3rd party ของ nodejs ซึ่งประกอบไปด้วย dotenv, express, express-fileupload, nodemon, aws-sdk

เริ่มเลย

Create space ใน digitalOcean
หน้าตา Space ของเราที่ชื่อ myspacev1
นี้เป้นลิส space ของผมที่สร้างไว้ทดลอง
หลังจาก gennerate key

พอเข้ามาหน้านี้ให้เราคลิกที่ปุ่มขวาบน Manage Keys เพื่อไปทำการขอ Key, Secret key ในการขอเข้าใช้งาน space ของเรา

หลังจากนั้นให้เรามาที่ Code ของเราซึ่งผมได้วาง Strcture Project ง่ายๆ เอาไว้ก่อนอื่นเราต้องติดตั้ง package ที่ผมพิมพ์ไว้ด้านบน

npm install express express-fileupload nodemon aws-sdk dotenv

อธิบายเพิ่มเติม
dotenv สำหรับเก็บค่า config ที่ไม่สามารถเปิดเผยได้เช่น key ต่างๆ ที่เราไปขอมาจาก Space DigitalOcean ข้างบน

aws-sdk พระเอกของเราซึ่งเราจะใช้ในการ put ไฟล์ที่เราจะอัพโหลดเข้าไปใน space


ตัวอย่าง Structure project ทั้งหมดอยู่ในนี้นะครับ https://github.com/najaroen/upload-file-to-digitalocean ผมยกตัวอย่างส่วนที่สำคัญออกมาเพื่อให้เห็นภาพ

ในตัวอย่างนี้ผมจะแบ่ง router ของเป็น 3 router เพื่อเป็นตัวอย่างคือ

  1. สำหรับ Upload file
  2. สำหรับเช็คไฟล์ใน space
  3. สำหรับขอ Url ในการ Download
// router
router.post('/upload-file', UploadController.uploadfile)
router.get('/list-file-space', UploadController.listFile)
router.get('/get-url-file/:name', UploadController.geturlDownloadFile)
// controller
const AWS = require('aws-sdk');
AWS.config.update({
    accessKeyId: process.env.SPACES_ACCESS_KEY_ID, // <<=== เก็บ config ไว้ใน .env
    secretAccessKey: process.env.SPACES_SECRET_ACCESS_KEY // <<=== เก็บ config ไว้ใน .env
});

const spacesEndpoint = new AWS.Endpoint(process.env.END_POINT); // <<=== เก็บ config ไว้ใน .env
const s3 = new AWS.S3({endpoint: spacesEndpoint});

exports.uploadfile = (req, res, next) => {
    if(!req.files && req.files.file) {
        res.status(400).json({
            message:'no file upload',
            status: false
        })
    } else {
        let params = { 
            Bucket: process.env.BUCKET_NAME,  // <<=== เก็บ config ไว้ใน .env
            Key: new Date().getMilliseconds().toString(),  // <<=== ชื่อที่เราจะตั้งให้ไฟล์นั้น
            Body: req.files.file.data,
            ACL: 'public-read', // <<=== ให้ไฟล์นี้เป็น public
        }
        s3.putObject(params, (err, data) => {
            if(err) {
                res.status(400).json({
                    message:'upload error '+ err.message,
                    status: false
                })
            } else {
                res.status(201).json({
                    message:'success',
                    status: true
                })
            }
        })     
    }
} 
// controller
exports.listFile = (req, res, next) => {
    let params = {
        Bucket: process.env.BUCKET_NAME,
    };
    let ListItems = [];
    s3.listObjects(params, (err, data) => {
        if (err) console.log(err, err.stack);
        else {
            data['Contents'].forEach((obj) =>{
                ListItems.push(obj['Key'])
            })
            res.status(200).json({
                message:'success',
                status: true,
                data: ListItems
            })
        };
    });
}

นี้คือฟังชั่นสำหรับเรียกดูไฟล์ที่เราอัพโหลดไปบน Space

exports.geturlDownloadFile = (req, res, next) => { 
const expireSeconds = 60 * 5
const url = s3.getSignedUrl('getObject', 
     { Bucket: process.env.BUCKET_NAME, 
      Key: req.params.name, // <== อันนี้คือชื่อไฟล์ที่เราจะไปเรียก url ออกมา
      Expires: expireSeconds // <== อายุการใช้งานของ url
     }); 
      res.status(200).json({ 
                message:'success', 
                status:true, data:url 
    })
  }

ฟังก์ชั่นสำหรับเรียก Url สำหรับ Download file

ทดสอบกัน

ทดสอบยิง api ด้วย postman โดยการอัพ video
เช็คดูไฟล์ที่อัพขึ้นมา นั้นไงมาแล้ว
ทดสอบยิง apiเช็คไฟล์ที่อยู่บน Space ด้วย postman
ทดสอบยิง api ขอ url ของไฟล์ อยู่บน Space ด้วย postman
นี้คือไฟล์ .env ที่ว่าครับสำหรับเก็บ config ค่าต่างที่เราต้องการ

ตัวอย่าง source code https://github.com/najaroen/upload-file-to-digitalocean

นอกจากนี้ยังมีตัวอย่างการใช้งานเพิ่มเติม https://www.digitalocean.com/docs/spaces/resources/s3-sdk-examples/

สรุป

นอกจากการใช้งาน Space ของ digitalOcean แล้วยังมีเจ้าอื่นให้ได้ลองใช้งานกัน ซึ่งในตัวอย่างที่ทำมาเห็นได้เลยว่าไม่ยากแต่มีเพียงไม่กี่ขั้นตอน เพื่อนๆ ยังสามารถนำไปประยุกต์ใช้กับงานของตัวเองได้เช่นระบบที่ต้องเก็บข้อมูลประเภทไฟล์ เมื่อทำแบบนี้แล้วทำให้ตัวงานของเราไม่บวมเกินไป หากมีอะไรที่ผิดพลาดต้องขออภัยด้วยน่ะครับตัวคนเขียนเองยังมือใหม่มากๆ หากมีข้อสงสัยก็ถามาได้เลยครับ

ก่อนหน้า
ถัดไป