class LambdaWrap::ApiGateway

The ApiGateway class simplifies creation, deployment, and management of API Gateway objects. The specification for the API MUST be detailed in a provided Open API Formatted file (fka Swagger).

@!attribute [r] specification

@return [Hash] The Swagger spec parsed into a Hash

@since 1.0

Attributes

specification[R]

Public Class Methods

new(options) click to toggle source

Initializes the APIGateway Manager Object. A significant majority of the configuration of your API should be configured through your Swagger File (e.g. Integrations, API Name, Version).

@param [Hash] options The Options initialize the API Gateway Manager with. @option options [String] :path_to_swagger_file File path the Swagger File to load and parse. @option options [String] :import_mode (overwrite) How the API Gateway Object will handle updates.

Accepts <tt>overwrite</tt> and <tt>merge</tt>.
# File lib/lambda_wrap/api_gateway_manager.rb, line 19
def initialize(options)
  options_with_defaults = options.reverse_merge(import_mode: 'overwrite')
  @path_to_swagger_file = options_with_defaults[:path_to_swagger_file]
  @specification = extract_specification(@path_to_swagger_file)
  @api_name = @specification['info']['title']
  @api_version = @specification['info']['version']
  @import_mode = options_with_defaults[:import_mode]
end

Public Instance Methods

delete(client, region = 'AWS_REGION') click to toggle source

Deletes all stages and API Gateway object. @param client [Aws::APIGateway::Client] Client to use with SDK. Should be passed in by the API class. @param region [String] AWS Region string. Should be passed in by the API class.

Calls superclass method
# File lib/lambda_wrap/api_gateway_manager.rb, line 91
def delete(client, region = 'AWS_REGION')
  super
  api_id = get_id_for_api(@api_name)
  if api_id
    options = {
      rest_api_id: api_id
    }
    @client.delete_rest_api(options)
    puts "Deleted API: #{@api_name} ID:#{api_id}"
  else
    puts "API Gateway Object #{@api_name} not found. Nothing to delete."
  end
  true
end
deploy(environment_options, client, region = 'AWS_REGION') click to toggle source

Deploys the API Gateway Object to a specified environment

@param environment_options [LambdaWrap::Environment] The environment to deploy @param client [Aws::APIGateway::Client] Client to use with SDK. Should be passed in by the API class. @param region [String] AWS Region string. Should be passed in by the API class.

Calls superclass method
# File lib/lambda_wrap/api_gateway_manager.rb, line 33
def deploy(environment_options, client, region = 'AWS_REGION')
  super
  puts "Deploying API: #{@api_name} to Environment: #{environment_options.name}"
  @stage_variables = environment_options.variables || {}
  @stage_variables.store('environment', environment_options.name)

  api_id = get_id_for_api(@api_name)
  service_response =
    if api_id
      options = {
        fail_on_warnings: false, mode: @import_mode, rest_api_id:
        api_id, body: File.binread(@path_to_swagger_file)
      }
      @client.put_rest_api(options)
    else
      options = {
        fail_on_warnings: false,
        body: File.binread(@path_to_swagger_file)
      }
      @client.import_rest_api(options)
    end

  raise "Failed to create API gateway with name #{@api_name}" if service_response.nil? || service_response.id.nil?

  if api_id
    "Created API Gateway Object: #{@api_name} having id #{service_response.id}"
  else
    "Updated API Gateway Object: #{@api_name} having id #{service_response.id}"
  end

  create_stage(service_response.id, environment_options)

  service_uri = "https://#{service_response.id}.execute-api.#{@region}.amazonaws.com/#{environment_options.name}/"

  puts "API: #{@api_name} deployed at #{service_uri}"

  service_uri
end
teardown(environment_options, client, region = 'AWS_REGION') click to toggle source

Tearsdown environment for API Gateway. Deletes stage.

@param environment_options [LambdaWrap::Environment] The environment to teardown. @param client [Aws::APIGateway::Client] Client to use with SDK. Should be passed in by the API class. @param region [String] AWS Region string. Should be passed in by the API class.

Calls superclass method
# File lib/lambda_wrap/api_gateway_manager.rb, line 77
def teardown(environment_options, client, region = 'AWS_REGION')
  super
  api_id = get_id_for_api(@api_name)
  if api_id
    delete_stage(api_id, environment_options.name)
  else
    puts "API Gateway Object #{@api_name} not found. No environment to tear down."
  end
  true
end
to_s() click to toggle source
Calls superclass method
# File lib/lambda_wrap/api_gateway_manager.rb, line 106
def to_s
  return @api_name if @api_name && @api_name.is_a?(String)
  super
end

Private Instance Methods

create_stage(api_id, environment_options) click to toggle source
# File lib/lambda_wrap/api_gateway_manager.rb, line 123
def create_stage(api_id, environment_options)
  deployment_description = "Deploying API #{@api_name} v#{@api_version}\
    to Environment:#{environment_options.name}"
  stage_description = "#{environment_options.name} - #{environment_options.description}"
  options = {
    rest_api_id: api_id, stage_name: environment_options.name,
    stage_description: stage_description, description: deployment_description,
    cache_cluster_enabled: false, variables: environment_options.variables
  }
  @client.create_deployment(options)
end
delete_stage(api_id, env) click to toggle source
# File lib/lambda_wrap/api_gateway_manager.rb, line 113
def delete_stage(api_id, env)
  options = {
    rest_api_id: api_id, stage_name: env
  }
  @client.delete_stage(options)
  puts 'Deleted API gateway stage ' + env
rescue Aws::APIGateway::Errors::NotFoundException
  puts "API Gateway stage #{env} does not exist. Nothing to delete."
end
extract_specification(file_path) click to toggle source
# File lib/lambda_wrap/api_gateway_manager.rb, line 135
def extract_specification(file_path)
  raise ArgumentError, "Open API Spec (Swagger) File does not exist: #{file_path}!" unless File.exist?(file_path)
  spec = Psych.load_file(file_path)
  raise ArgumentError, 'LambdaWrap only supports swagger v2.0' unless spec['swagger'] == '2.0'
  raise ArgumentError, 'Invalid Title field in the OAPISpec' unless spec['info']['title'] =~ /[A-Za-z0-9]{1,1024}/
  spec
end
get_id_for_api(api_name) click to toggle source
# File lib/lambda_wrap/api_gateway_manager.rb, line 143
def get_id_for_api(api_name)
  response = nil
  loop do
    options = {
      limit: 500
    }
    options[:position] = response.position unless !response || response.position.nil?
    response = @client.get_rest_apis(options)
    api = response.items.detect { |item| item.name == api_name }
    return api.id if api
    return if response.items.empty? || response.position.nil? || response.position.empty?
  end
end