S3 integration with Vapor
We use S3 to store files in the cloud for easy and secure access. We use some Vapor packages to integrate Vapor application with S3. The implementation is different for the Vapor versions.
Vapor 4 Integration
Package.swift
Add the S3 package to the dependencies and target.
dependencies: [
.package(name: "AWSSDKSwift", url: "https://github.com/swift-aws/aws-sdk-swift.git", from: "4.7.0"),
],
targets: [
.target(name: "App", dependencies: [
.product(name: "S3", package: "AWSSDKSwift"),
]),
]
Model/Controller
Put Object:
import S3
struct FileRequest: Content {
var file: File?
}
let fileRequest = try req.content.decode(FileRequest.self)
let file = fileRequest.file
let data = Data(file.data.readableBytesView)
let putObjectRequest = S3.PutObjectRequest(acl: .publicRead, body: data, bucket: "bucket", contentLength: Int64(data.count), key: "path")
let s3 = S3(accessKeyId: Environment.get("S3_KEY")!, secretAccessKey: Environment.get("S3_SECRET")!, region: .region)
return s3.putObject(putObjectRequest).flatMap { _ in
// Store the path to db for future reference
}
Get Object:
let s3 = S3(accessKeyId: Environment.get("S3_KEY")!, secretAccessKey: Environment.get("S3_SECRET")!, region: .region)
return s3.getObject( S3.GetObjectRequest(bucket: "bucket", key: "path")).flatMapThrowing({ response in
return String(data: response.body!, encoding: .utf8)!
})
Vapor 3 Integration
Package.swift
Add the S3 package to the dependencies and target.
dependencies: [
.package(url: "https://github.com/LiveUI/S3.git", from: "3.0.0"),
],
targets: [
.target(name: "App", dependencies: ["S3",]),
]
configure.swift
Register the service:
import S3
try services.register(s3: S3Signer.Config(accessKey: Environment.get("S3_KEY")!, secretKey: Environment.get("S3_SECRET")!, region: Region(name: .region)), defaultBucket: "bucket")
Model/Controller
Put Object
import S3
struct FileRequest: Content {
var file: File?
}
return try req.content.decode(FileRequest.self).flatMap { fileRequest in
let file = File.Upload(data: Data(fileRequest.file.data.withByteBuffer { $0 }), bucket: "bucket", destination: "path", access: .publicRead)
let s3 = try req.makeS3Client()
return try s3.put(file: file, headers: [:], on: req).flatMap { _ in
// Store the path to db for future reference
}
}
Get Object:
let s3: S3Client = try S3(defaultBucket: Environment.get("DEFAULT_PUBLIC_BUCKET")!, signer: req.makeS3Signer())
return try s3.get(file: "path", on: req).map({ response in
return String(data: response.data, encoding: .utf8)!
})