This article is AWS Beginner Advent Calendar 2019 This is the article on the 14th day of. I would appreciate it if you could point out any mistakes.
In Boto3, some services have a resource API (called by boto3.reosurce ('service name')). The resource API is more abstract than the client API and can be implemented without writing unnecessary information, so if you can do the same with each API, it is better to give priority to the resource API.
First, let's reconfirm what Boto3, the client API, and the resource API were. After that, if you use both APIs, take up the usage patterns of SQS, S3, and DynamoDB one by one and compare them to see how they differ. Finally, I write a list and impressions of the services for which the resource API is currently provided.
The AWS SDK provided with Python is used to connect from code to various AWS services (EC2, DynamoDB, S3, etc.). The API reference can be found in the following resources: Boto 3 Documentation
There are two main APIs: client API, which is a low-level API, and resource API, which is a high-level API. Specifically, it is called with the following description.
# Client API
boto3.client('sqs')
# Resource API
boto3.resource('sqs')
Next, let's check what characteristics each API has.
This method has a one-to-one correspondence with the HTTP API provided by the AWS service. HTTP API It is fully mapped to, so you can do everything that the API can do. However, since it is a general-purpose setting, it is necessary to set the parameters to the API directly to the method. The following is an example of executing SQS send_message. QueueUrl etc. used in API are specified.
import boto3
#SQS client API version
sqs = boto3.client('sqs')
response = sqs.send_message(QueueUrl='https://sqs.us-east-2.amazonaws.com/123456789012/MyQueue', MessageBody='...')
Source: Boto3 Client API documentation (send_message) https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sqs.html#SQS.Client.send_message
It is a high-level abstraction API compared to the client API. It is easier for developers to handle by inserting an abstract class in between instead of directly mapping with the API. Here, as an example, we will describe an example of sending_message with the resource API in the same way as the client API.
queueName='target-queue-name'
#SQS resource API version
sqs = boto3.resource('sqs')
response = sqs.get_queue_by_name
QueueName = queueName
).send_message(
MessageBody = '...'
)
Reference source: "I tried using" Service Resource "in Boto3 (Python) (Lambda)" https://cloudpack.media/16114
Compared to the client API, you can write a message by querying the queue name without writing the SQS URL in the code. Developers only need to write the name of the queue because they don't have to be aware of the URL of the queue each time.
Next, compare the S3 client API and resource API. As an example, write the code to get the file name from the bucket.
#Common constant(Bucket and file prefixes in S3)
BUCKET_NAME= "xxx-bucket"
S3_PREFIX = "image-file-done/"
#S3 client API version
s3_client = boto3.client('s3')
#Return type:<class 'dict'>
s3_objects = s3_client.list_objects_v2(Bucket=BUCKET_NAME, Prefix=S3_PREFIX)
for filename in s3_objects['Contents']:
print('client:'+filename['Key'])
#S3 resource API version
s3_resource = boto3.resource('s3')
#Return type:<class 'boto3.resources.collection.s3.Bucket.objectsCollection'>
s3_objects = s3_resource.Bucket(BUCKET_NAME).objects.filter(Prefix=S3_PREFIX)
for filename in s3_objects:
print('resource:'+filename.key)
It's almost the same until the call, but the type after the call is different. When called by the client API, it is returned in dictionary type, so it is necessary to retrieve data that is conscious of the dictionary type format that is returned each time it is implemented. If it is a resource API, it is an object for boto3, so even if you use the resource API with other services, you can write code with a similar description.
Finally, compare the DynamoDB client API and resource API. Especially here, I don't understand the Boto3 document well, and it seems that I often copy it by mistake with reference to other descriptions. (It's my old self ...)
#Common constant(Table name, hash key name, sort key name)
TABLE_NAME='XXXXX_IFO'
HASH_KEY_NAME='XXXXX_CODE'
SORT_KEY_NAME='DATE_TIME'
#DynamoDB client version
dynamodb_client = boto3.client('dynamodb')
#Return type: <class 'dict'>
response = dynamodb_client.get_item(
TableName=TABLE_NAME,
Key={
HASH_KEY_NAME:{
'S': '54620100'
},
SORT_KEY_NAME:{
'S': '2019050621'
}
}
)
#DynamoDB resource API
dynamodb_resource = boto3.resource('dynamodb')
table = dynamodb_resource.Table(TABLE_NAME)
#Return type: <class 'dict'>
response = table.get_item(
Key={
HASH_KEY_NAME: '54620100',
SORT_KEY_NAME: '2019050621'
}
)
I wrote it in the client API after a long time, but it is a little difficult because I write the parameters in the same format as CLI. The return type itself is a dictionary type, but the operation inside the table can be done from the Table object, and the description of the Key item is considerably easier because you do not have to write the type information one by one.
The resource API offers a limited number of services. Specifically, the following services are supported.
Reference source: "Boto 3 Documentation" https://boto3.amazonaws.com/v1/documentation/api/latest/index.html
When using the above services, it seems necessary to first consider the resource API before using the client API. DynamoDB is a resource in Boto3's CodeExamples (sample documentation), but since other EC2 and CloudWatch are clients, it seems that you need to look at Available Services as well as CodeExamples.
Until now, I used the client API and resource API without much consciousness, so I have summarized the results of various investigations as a reflection. As you can see from the SQS example, there is no need to write unnecessary information in the code part, so in the future I will first check if the service has a resource API, and if it is provided, think about whether it can be used well and then use the client API. I want to use it. It seems that there are many implementations written in the client API on Qiita and the net, so I would like to increase the information on the resource API by writing articles myself in the future.
Recommended Posts