Mục Tiêu
- Lưu ảnh lên Amazon Simple Storage Service
- Lấy ảnh từ Amazon Simple Storage Service, giới hạn TTL
Chuẩn Bị
- Bạn có đọc thêm series để nắm căn bản: https://viblo.asia/s/golang-lambda-serverless-vElaB8eD5kw
API Lưu Image
- Image được input dưới dạng base64
Cấu Hình ENV
Trong file serverless.yaml, add 2 env
provider: environment: S3_BUCKET: "images-dev-serverlessdeploymentbucket-1g3trol0zorpp" IMAGE_BLOG: "image-blog/"
- Sau khi deploy thành công, thì truy cập aws-console search S3 service để check bucket của project => copy và bỏ vào env
- Env
IMAGE_BLOG
là image sẽ được lưu sub-folder trong bucket
List function Code
Tạo AWS session
func CreateSession(req AwsReq) *session.Session { sess := session.Must(session.NewSessionWithOptions(session.Options{ SharedConfigState: session.SharedConfigEnable, })) return sess
}
- Để có thể tạo được session, yêu cầu cấu hình credential trước. Checkout Cấu Hình AWS Credential để cấu hình credential
Func kiểm tra size của image
// fn upload image to s3, request iamge is base64
func CheckSizeBase64(baseImage *string) error { sizeByte := base64.StdEncoding.DecodedLen(len(*baseImage)) sizeRe := 5000000 if sizeByte > sizeRe { err := fmt.Errorf("size image large, require size %d and size input %d", sizeRe, sizeByte) return err } return nil
}
- Image từ client dưới dạng base64 => check size bằng cách kiểm tra số lượng kí tự của base64
- Func check số lượng kí tự vượt quá 5 triệu thì sẽ báo lỗi
Func Lưu image đến s3
func StoreS3(ctx context.Context, reqDTO StoreS3Req) (*s3.PutObjectOutput, StoreS3Reponse, error) { var ( dataRes = StoreS3Reponse{} err error putOut = &s3.PutObjectOutput{} ) if reqDTO.BaseImage == nil { return putOut, dataRes, fmt.Errorf("base64 of image is require") } if len(*reqDTO.BaseImage) == 0 { return putOut, dataRes, fmt.Errorf("byte image decode empty") } splitBase := strings.Split(*reqDTO.BaseImage, "base64,") var newBase string if len(splitBase) > 1 { newBase = splitBase[1] } else { newBase = splitBase[0] } byteImage, err := base64.StdEncoding.DecodeString(newBase) if err != nil { fmt.Println("image decode string err", err) return putOut, dataRes, err } mimeType := http.DetectContentType(byteImage) fmt.Println("mime type:", mimeType) if !strings.Contains(mimeType, "jpeg") && !strings.Contains(mimeType, "png") { return putOut, dataRes, fmt.Errorf("mime type error") } byteReader := bytes.NewReader(byteImage) dataRes.PathImage = reqDTO.PathImage session := CreateSession(AwsReq{ CustomEndpoint: reqDTO.CustomEndpoint, }) putOut, err = s3.New(session).PutObject(&s3.PutObjectInput{ Body: byteReader, Bucket: aws.String(GetS3Bucket()), Key: aws.String(dataRes.PathImage), ContentType: &mimeType, }) return putOut, dataRes, err
}
- Line code
mimeType := http.DetectContentType(byteImage)
kiểm tra type của image, chỉ handle 2 dạng type ['png','jpeg']
Một số func phụ khác:
- Get bucket name từ environment:
func GetS3Bucket() string { bucket := os.Getenv("S3_BUCKET") if bucket != "" { return bucket } log.Default().Println("GetS3Bucket default value:", "pkg.BucketDefault") return "pkg.BucketDefault"
}
=> lấy bucket-name thừ environment, nếu env rỗng thì sử dụng bucket-name mặc định.
Test API
- Request data:
{ "requestId":"", "requestTime":"", "data": { "file_name": "ducnp", "name":"ducnp5-test1", "phone":"0335288888", "partner_id":"myst", "user_id":"ducnp", "image":"****am6firEVHTsD//2Q==****" }
}
- Response data:. Truy cập S3 thì sẽ thấy ảnh đã lưu thành công.
ERROR
- Có thể xuất hiện lỗi này: ==> truy cập vào cloud-watch, để check error. Thường là do chưa cấp quyền cho Role access vào S3.
API Get Image
- Tương tự như lưu ảnh, API get image thì chỉ khác 1 chỗ đó là hàm
PresignUrl
List function Code
PresignUrl
func PresignUrl(reqAws AwsReq, presign PresignUrlReq) (string, error) { var ( url string err error ) clientS3 := CreateS3Client(reqAws) req, _ := clientS3.GetObjectRequest(&s3.GetObjectInput{ Bucket: aws.String(presign.Bucket), Key: aws.String(presign.KeyPath), }) url, err = req.Presign(presign.UrlTtl) if err != nil { return url, fmt.Errorf("presign url err %s", err) } return url, err
}
- Trong func có thuộc tính
TTL
là giới hạn thời gian access đến image.
Test API
- Request:
{ "requestId":"", "requestTime":"", "data": { "pathImage": "image-blog/0335288888landucnp5-test1" }
}
- Response:
{ "data": { "url": "https://images-dev-serverle****blog/0335288888landucnp5-test1?X-Amz-***mz-Credential=ASIAQ52H7T***" }, "responseCode": "00", "responseId": "8b2f9168-4ad4-4f6c-b0b6-8b78f3d7c99d", "responseMessage": "successfully", "responseTime": "2023-02-05T01:28:17Z"
}
==> copy url và mở bằng browser để xem.
- Image hết hạn:
Contact
- facebook: https://www.facebook.com/phucducdev/
- gmail: ducnp09081998@gmail.com or phucducktpm@gmail.com
- linkedin: https://www.linkedin.com/in/phucducktpm/
- hashnode: https://hashnode.com/@OpenDev
- telegram: https://t.me/OpenDevGolang