AWS Developer Tools Blog

AWS SDK Core Response Structures

I blogged recently about how the code is now available for AWS SDK Core. This new repository is the basis for what will become version 2 of the AWS SDK for Ruby.

We have not cut a public gem for AWS SDK Core yet. Instead, we have published the work-in-progress code to GitHub for the community to see. We hope to get a lot of feedback on features as they are developed. In an effort to engage the community, I will be blogging about some of these new features and soliciting feedback. Our hope is to improve the overall quality of version 2 of the Ruby SDK through this process.

Today, I will talking about the new response structures.

V1 Response Strutures

In version 1 of the Ruby SDK, the low-level clients accepted a hash of request parameters, and then returned response data as a hash. Here is a quick example:

# hash in, hash out
response = AWS::S3::Client.new.list_buckets(limit: 2)
pp response.data

{:buckets=>[
  {:name=>"aws-sdk", :creation_date=>"2012-03-19T16:37:04.000Z"},
  {:name=>"aws-sdk-2", :creation_date=>"2013-09-27T16:17:02.000Z"}],
 :owner=>
  {:id=>"...",
   :display_name=>"..."}}

This approach is simple and flexible. However, it gives little guidance when exploring a response. Here are some issues that arise from using hashes:

  • Attempts to access unset response keys return a nil value. There is no way to tell if the service omitted the value or if the hash key contains a typo.

  • Operating on nested values is a bit awkward. To collect bucket names, a user would need to use blocks to access attributes:

    data[:buckets].map{ |b| b[:name] }
  • The response structure gives no information about what other attributes the described resource might also have, only what is present currently.

V2 Response Structures

In AWS SDK Core, we take a different approach. We use descriptions about the complete response structure to construct Ruby Struct objects. Here is the sample from above with version 2:

Aws::S3.new.list_buckets.data
#=> #<struct 
 buckets=
  [#<struct name="aws-sdk", creation_date=2012-03-19 16:37:04 UTC>,
   #<struct name="aws-sdk-2", creation_date=2013-09-27 16:17:02 UTC>],
 owner=
  #<struct 
   id="...",
   display_name="...">>

Struct objects provide the following benefits:

  • Indifferent access with strings, symbols, and methods:

    data.buckets.first.name
    data[:buckets].first[:name]
    data['buckets'].first['name']
    
  • Operating on nested values possible using Symbol-to-Proc semantics:

    data.buckets.map(&:name)
    
  • Accessing an invalid property raises an error:

    data.buckets.first.color
    #=> raises NoMethodError: undefined method `color' for #<struct ...>
    

Feedback

What do you think about the new response structures? Take a moment to checkout the new code and give it a spin. We would love to hear your feedback. Issues and feature requests are welcome. Come join us on GitHub.