How to config AWS S3 file storage to use by Kotlin Spring Boot
In case you don’t know what AWS S3 file storage is, it is a scalable, high-speed, web-based cloud storage service designed by Amazon Web Services (AWS). It is designed to make web-scale computing easier for developers by providing a simple web services interface that can be used to store and retrieve any amount of data, at any time, from anywhere on the web. For more information: https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html
Now, it’s time to dive into how to config the AWS S3 file storage.
Pre-Requirements:
- A pre-existing account with AWS S3 permission.
- IntelliJ as IDE to write Kotlin Spring Boot. (or other choice of IDE of your liking)
You first need a pre-existing account with AWS S3 permission to do this. If you don’t have one, you can register an account with AWS via this link: https://portal.aws.amazon.com/billing/signup
After you have the account, you will need your AWS credentials including ACCESS_KEY_ID and SECRET_ACCESS_KEY which you can find with this method: https://docs.aws.amazon.com/AmazonS3/latest/userguide/viewing-bucket-key-settings.html
Let’s start by setting up the bucket to store our files
Note: The S3 system will not allow the creation of a bucket with a name that already exists as it serves as the access URL.
Once the bucket has been set up, you can proceed to creating a folder and uploading the file.
Then it’s time to set your Kotlin Spring Boot project with Spring Web Dependency, you can set the dependency by using https://start.spring.io/ if you don’t want to do it manually.
Here's what the dependency is going to look like.
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")
}
To proceed, you must include your AWS credentials in the project environment. You can configure them by going to the top menu.
Run > Edit configuration > Kotlin > file.kt
If you are unable to locate the configuration, you can add it by selecting the option below.
Select Main Class as file “application.kt”.
Then you can set the environment variable by inserting your AWS credentials and then clicking Apply.
Note: I used the temporary key for testing in this case, hence AWS_SESSION_TOKEN is included.
After completing the project setup, it's time to start coding. I will begin by creating the project's Controller and Service.
Project’s Controller:
@RestController
@RequestMapping("/download")
public class FileController(
val downloadService:DownloadService
) {
@GetMapping("/file")
fun getFile(@RequestParam("keyName")keyName :String)
: RedirectView {
return RedirectView(downloadService
.download("Name of your created bucket",keyName))
}
}
Project’s 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()
}
}
The API will be accessed through this URL: http://localhost:8080/download/file where the RequestParam is keyName which represents the path of the object in AWS S3. (You can also go to this path directly to retrieve the file as well)
Finally, it’s time to test our program by using Postman to call our API.
To get this done, you can request an API using a specific path that we've mapped out. You just need to use the Key and Value of the keyName that we've created as a RequestParam in the controller. This keyName corresponds to the object's path on AWS S3. Alternatively, you can also access the path directly on your web browser.
The file we received is currently in preview mode and was not directly downloaded upon request. To fix this, we can change the Metadata type value in the bucket we created to “application/octet-stream”. This will allow for direct downloads of the file.
Lastly! You can now download AWS S3 files using Kotlin Spring Boot.
Related Links:
Original Blog in Thai version by jutamart kotkaew
Doc SDK for Kotlin: https://docs.aws.amazon.com/sdk-for-kotlin/latest/developer-guide/home.html
Set up Environment in Kotlin: https://www.twilio.com/en-us/blog/set-up-env-variables-intellij-idea-java
Git Repository: aws-doc-sdk-examples