Getting started S3 with Kotlin Spring Boot
หากอยากรู้ว่า S3 คือ อะไร : https://www.blognone.com/node/101588
Pre-requisite :
- account aws ที่มี permission in s3
- AWS credentials : ที่จะประกอบด้วย ACCESS_KEY_ID , SECRET_ACCESS_KEY
- project Kotlin springboot with Spring Web Dependency https://start.spring.io/
โดย IDE ที่ใช้จะเป็น IntelliJ
การสร้าง Bucket
การสร้าง bucket เพื่อเก็บข้อมูล โดยการตั้งชื่อจะต้องไม่ซ้ำกับชื่อ bucket ทั้งระบบของ S3 ซึ่งชื่อที่ตั้งไว้จะกลายเป็นส่วนหนึ่งของ URL สำหรับให้เข้าถึง
** โดยในตัวอย่างเป็นการตั้งค่าเป็นตามที่ S3 แนะนำ
หลังจากที่ ได้ bucket มาเรียบร้อยแล้ว ก็ทำการ สร้าง folder และสามารถ upload file ได้เลย
มาต่อกันในส่วนของ API เพื่อเรียกใช้ S3 กัน
Dependencies : Gradle Build Tool
dependencies {
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("aws.sdk.kotlin:s3:1.0.40")
testImplementation("org.springframework.boot:spring-boot-starter-test")
}
Set env by edit configuration
ไปที่แถบด้านบน
Run > Edit configuration > Kotlin > file.kt
หากไม่มีทำการเพิ่ม กดปุ่ม + > Add New configuration > Kotlin
เลือก Main class: เป็น file Application.kt
set environment variable : กรอก AWS credentials จากนั้น Apply
สร้าง Controller
@RestController
@RequestMapping("/download")
public class FileController(
val downloadService:DownloadService
) {
@GetMapping("/file")
fun getFile(@RequestParam("keyName")keyName :String)
: RedirectView {
return RedirectView(downloadService
.download("ชื่อของ bucket ที่สร้าง",keyName))
}
}
สร้าง Service
class DownloadService {
fun download(bucketName: String,
keyName: String): String = runBlocking {
val s3 = S3Client.fromEnvironment() { region = "ap-southeast-1" }
val bucketName = bucketName
val keyName = keyName
val presignedUrl = getObjectPresigned(s3, bucketName, keyName)
return@runBlocking presignedUrl
}
suspend fun getObjectPresigned(s3: S3Client,
bucketName: String,
keyName: String): String {
// Create a GetObjectRequest.
val unsignedRequest = GetObjectRequest {
bucket = bucketName
key = keyName
}
// Presign the GetObject request.
val presignedRequest = s3.presignGetObject(unsignedRequest, 24.hours)
return presignedRequest.url.toString()
}
}
โดย API จะถูกเรียกด้วย path: http://localhost:8080/download/file ที่ส่ง Request Param เป็น keyName ซึ่ง keyName ที่ส่งไปนี้จะเป็น path ของ object ใน S3 (สามารถกดเข้าไปในไฟล์เพื่อ copy key มาได้เลย)
Postman call API
จากนั้นก็ทำการลองยิง Postman ตาม Path ที่ตั้งไว้ และใส่ Key และ Value ของ keyName ที่สร้างเป็น RequestParam ไว้ใน controller (path ของ object ใน S3) หรือสามารถนำ Path ไปวางที่ web browser ได้เช่นกัน
แก้ไข meta data เพื่อเปลี่ยน content type
เนื่องจากไฟล์ที่ได้ออกมายังเป็น file สำหรับ preview อยู่ สามารถแก้ไขให้สามารถ Download file ได้เลย โดยการเปลี่ยน type Metadata ใน Bucket ให้มี Value = application/octet-stream
เท่านี้เราก็สามารถDownload file จาก S3 ได้แล้วค่ะ
Sources :
Doc SDK for Kotlin : https://docs.aws.amazon.com/sdk-for-kotlin/latest/developer-guide/home.html
Set up Enviroment in Kotlin : https://www.twilio.com/en-us/blog/set-up-env-variables-intellij-idea-java
Git Ropo : aws-doc-sdk-examples