Soto icon

Soto

Getting Started

Before you start you are going to need an Amazon Web Services (AWS) account, an Identity and Access Management (IAM) user account and access key credentials. The credentials identify the user or role trying to access AWS resources. AWS provide enough documentation on creating users and credentials so I won't repeat that here.

Creating an AWSClient

Once you have your credentials (accessKeyId and secretAccessKey) you are ready to use Soto. First we need to create an AWSClient. The AWSClient does all the communication with AWS. In this situation we are going to supply the credentials directly to the client, but there are various methods for supplying credentials. You can read more about them here.

let awsClient = AWSClient(
    credentialProvider: .static(accessKeyId: myAccessKeyId, secretAccessKey: mySecretAccessKey)
)

Create a service object

In our sample we are going to create an S3 bucket, upload some text to a file in the bucket, download it and then delete the file and bucket. To work with S3 we need to import the SotoS3 library and create an S3 service object. While the AWSClient does the actual communication with AWS, the service object provides the configuration and APIs for communicating with the service, in this case S3.

import SotoS3

let s3 = S3(client: awsClient, region: .euwest1)

The S3 object is initialized with the AWSClient we created earlier and the AWS region you want to work in.

Creating an S3 Bucket

The first action is to create the S3 bucket. You create a request object first and then call the createBucket function with that request object. This is the standard pattern for all the Soto functions.

let bucketName = "soto-getting-started-bucket"
let createBucketRequest = S3.CreateBucketRequest(bucket: bucketName)
try await s3.createBucket(createBucketRequest)

Upload an object to your bucket

We now upload some text to a file in your S3 bucket. To upload to a file called lorum.txt in our S3 bucket we use S3.putObject.

let lorumText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed..."
let putObjectRequest = S3.PutObjectRequest(
    body: .string(lorumText), 
    bucket: bucketName, 
    key: "lorum.txt"
)
try await s3.putObject(putObjectRequest)

Here we use a String as source for the object, but you can upload a Foundation Data with .data(), a SwiftNIO ByteBuffer with .byteBuffer(), stream data for an upload using .stream() or stream data from a file handle using .fileHandle().

Download your object

To download the object from your S3 bucket we use S3.getObject.

let getObjectRequest = S3.GetObjectRequest(bucket: bucketName, key: "lorum.txt")
let response = try await s3.getObject(getObjectRequest)
let body = response.body?.collect(upTo: 1_000_000)
assert(String(buffer: body) == lorumText)

This time we get the body from the response from the S3.getObject operation. The response object is of type S3.GetObjectOutput. The contents of the file downloaded can be found in S3.GetObjectOutput.body. This is an AWSHTTPBody which is a stream of data buffers. You can collect the whole of the stream into one buffer using the function collect(upTo:) and then convert that to a String.

Delete everything

At the end we want to delete the bucket. Before we delete the bucket we have to delete its contents ie the object we uploaded to it.

let deleteObjectRequest = S3.DeleteObjectRequest(bucket: bucketName, key: "lorum.txt")
try await s3.deleteObject(putObjectRequest)
let deleteBucketRequest = S3.DeleteBucketRequest(bucket: bucketName)
try await s3.deleteBucket(deleteBucketRequest)

And there you have it, a simple, although fairly useless operation. It should demonstrate calling AWS service operations with Soto is easy.