Tag: rubygems


Introducing Support for Generating Ruby SDKs in Amazon API Gateway

by Jingyi Chen | on | in Ruby | Permalink | Comments |  Share

We’re excited to announce support for generating Ruby SDKs from Amazon API Gateway. The Ruby SDKs you generated are compatible with Ruby 1.9 and later. Generated SDKs have first-class support for API keys, custom or AWS Identity and Access Management (IAM) authentication, automatic and configurable retries, exception handling, and all privileges of aws-sdk-core version 3 has as well. In this blog post, we’ll walk through how to create an example API and generate a Ruby SDK from that API. We also explore various features of the generated SDK. In this post, we assume you have some familiarity with API Gateway concepts.

Creating an example API

To start, let’s create an sample API by using the API Gateway console.
Open the API Gateway console, choose Create API, and then choose Example API. Then choose Import to create the example API.

This simple, example API has four straightforward operations:

  • A GET on the API root resource that returns HTML describing the API
  • A GET on the /pets resource that returns a list of Pets
  • A POST on the /pets resource that creates a new Pet
  • A GET on the /pets/{petId} resource that returns a specific Pet by ID

You can find more information about this example in the API Gateway documentation.

Deploying the API

Next, let’s deploy our API to a stage.
From Actions choose Deploy API.

On the stage deployment page, name the stage Test, and then choose Deploy.

After deploying, the SDK Generation tab is available. For Platform, choose Ruby
For Service Name, type Pet.

Choose Generate SDK, and then extract the downloaded SDK package.

The following are the configuration options available for the Ruby platform:

  • Service Name – Used to generate the Ruby gem namespace for your APIs.
  • Ruby Gem Name – The name of the Ruby gem your generated SDK code will be placed under. If you don’t provide a name, this defaults to the service name in lowercase, with the “sdk” suffix.
  • Ruby Gem Version – The version number for the generated Ruby gem. If you don’t provide a version number, this defaults to 1.0.0 if not provided.

These are basic Ruby gem configuration options. You can customize your Ruby gemspec in the generated SDK gem later.

Using the generated Ruby SDK gem

Navigate to the location of your downloaded SDK gem. The directory structure looks like the following.

Note
/features and /spec directories are currently left empty for integration and unit tests that you can add to the SDK. The generated SDK is fully documented for operations and shapes in the source code.

Exploring the SDK

Let’s explore the SDK by building a Ruby gem from the generated source, as follows.

# change to /pet-sdk directory
cd pet-sdk

# build the generated gem
gem build pet-sdk.gemspec
# then you can see pet-sdk-1.0.0.gem is available

Then, install the gem, as follows.

gem install pet-sdk-1.0.0.gem

Finally, create the client.

require 'pet-sdk'

client = Pet::Client.new

Features in the client

Now you have your own client that includes multiple features from the official AWS SDK for Ruby. These include default exponential backoff retries, HTTP wire logging options, configurable timeouts, and more.

For example:

require 'pet-sdk'
client = Pet::Client.new(
  http_wire_trace: true,
  retry_limit: 5,
  http_read_timeout: 50
 )

Making API calls

Let’s see all the API methods that are available and use your SDK’s built-in parameter validators to make a successful API call:

client.operation_names
# => [:create_pet, :get_api_root, :get_pet, :get_pets]

# get me all my pets
resp = client.get_pets

You should see a response like the following.

# I want the cat
client.get_pet
# ArgumentError: missing required parameter params[:pet_id]

# providing :pet_id
client.get_pet(pet_id: 2)
# ArgumentError: expected params[:pet_id] to be a String, got value 2 (class: Fixnum) instead.

# fix the value type
resp = client.get_pet(pet_id: "2")

Now you can see a correct response like the following.
If you have some familiarity with the AWS SDK for Ruby, you should find the experience similar to using an AWS service client.

Generate a Ruby SDK from an API

In addition to using the API Gateway console to generate a Ruby SDK, the get_sdk API is available in all of the AWS SDKs and tools, including the AWS SDK for Ruby.

For this example, we assume that you have some familiarity with the AWS SDK for Ruby. You can find a quick introduction to the SDK for Ruby here.

require 'aws-sdk-apigateway'

client = Aws::ApiGateway::Client.new(region: 'us-west-2')
resp = client.get_sdk({
  rest_api_id: MY_REST_API_ID, # required
  stage_name: DEPLOY_STAGE_NAME, # required
  sdk_type: "ruby", # required
  parameters: {
    "service.name" => "PetStore", # required
    "ruby.gem-name" => "pet",
    "ruby.gem-version" => "0.0.1"
  },
})

Final thoughts

This post highlights how to generate a Ruby client SDK for an API in API Gateway, and how to call the API using the generated SDK in an application. For more information about using a generated SDK, see your README.md file in the uncompressed generated SDK gem folder. Details of example usage of your API are also generated in source file documentation blocks.

Feedback

Please share your questions, comments, and issues with us on GitHub. Feel free to open a support ticket with AWS Support if you find an issue with your API model. You can also catch us in our Gitter channel.

Locking Dependency Versions with Bundler

by Loren Segal | on | in Ruby | Permalink | Comments |  Share

When writing a Ruby application or library that makes use of third-party dependencies, it is always best to keep track of those dependency versions. This is an easy thing to do with Bundler, but not everybody does it. We think you should, so here are some quick tips on how to get started.

Locking to Major Versions

Bundler works by providing a Gemfile that contains the list of third-party dependencies for your application or library. This list can specify library dependencies by a specific (or fuzzy) version, but it does not require the version field to be set.

Even though the version field is optional, we recommend that it should always be set to at least a "major version" of your dependencies. If those libraries use Semantic Versioning (SemVer), this means locking to all "1.x", "2.x", "3.x", or other major releases. You can do this in Bundler by using the fuzzy version check syntax:

gem 'some_dependency', '~> 1.0'

This locks the some_dependency gem to any version of 1.x, from 1.0 all the way to (but not including) 2.0. Without this check, you risk breaking your application build (or downstream consumers or your library) when the dependency releases a new major version. Instead, with this simple constraint, your application or library will not automatically pick up a new major version, and the risk of your code randomly breaking due to third-party changes should decrease greatly.

If you are a library developer and are not already following Semantic Versioning, we recommend that you read up on these versioning conventions and consider following them, as it makes your library much more reliable for downstream consumers. Your users will thank you.

Getting Specific

If you want to provide a more fine-grained constraint than a major version, it is possible to do so with the same fuzzy version check syntax as above. This might be necessary when using libraries that do not follow Semantic Versioning conventions. The only syntactic difference is that you also must specify the minor version that you want to lock into.

For example, to lock to any patchlevel release in a 1.5 minor version of a library, you can provide the following constraint:

gem 'some_dependency', '~> 1.5.0'

Note the extra ".0" suffix, which tracks the dependency through all 1.5.x releases. Without the ".0" suffix, the constraint would refer to any 1.x release that is greater than or equal to 1.5.

Notes for the AWS SDK for Ruby

The good news is that the AWS SDK for Ruby follows Semantic Versioning, which means we do not make backward-incompatible changes within a major release. To ensure that such changes will not make their way downstream to your application or library, it is best to always lock your version of the Ruby SDK to a major release. Since we are currently in our 1.x major version, you can do this with Bundler by specifying the aws-sdk dependency as follows:

gem 'aws-sdk', '~> 1.0'

This way you will not accidentally receive any backward-incompatible changes should we ever release a new major version of the Ruby SDK.

In Your Gem Specification

If you release your library and maintain a separate .gemspec file, you can (and should) use the same constraint syntax there too. You can see the RubyGems Specification Reference for more details, but in short, you simply need to list the dependency as:

spec.add_runtime_dependency 'some_dependency', '~> 1.0'

This will provide the same major version constraint that Bundler does for anybody who runs gem install yourgem.

Finishing Up

Specifying major versions for third-party dependencies in your Gemfile or .gemspec file is easy, and we should all be doing it. At the very least, providing a major version helps ensure that your library is more resistant to backward-incompatible changes coming from third-party code, and saves your downstream users from ending up with those breaking changes. As the community starts to make use of more third-party libraries in a single application or gem, it’s much more important to stay on top of dependency management and avoid these kinds of failures.