Help us understand the problem. What is going on with this article?

Heroku 謹製 環境変数を検証するライブラリ configvar

More than 3 years have passed since last update.

はじめに

本投稿は Heroku Advent Calendar 2016 の 第7日目の記事です。

※ いまは Heroku でも node.js が人気かと思いますが、 ruby 限定の話です。

Heroku でアプリケーションを稼動させていると、環境変数を利用する場面が多々あると思います。ruby だと settingslogic とか config(rails-config) を使って、環境ごとに環境変数を設定しているんじゃないかと思います。Heroku 謹製の gem で configvar という環境変数で設定されている値を検証する gem があったのでここで紹介してみます。それオワコンだよ、とか config でできるよって場合はごめんなさい。

スクリーンショット 2016-12-07 14.43.37.png

configvar でできること

  • 必須な環境変数とそうじゃない環境変数の明示
  • 上記の環境変数の存在有無の検証
  • 環境変数に設定されている値の検証

Ruby スクリプトでやってみる

hello.rb
require "configvar"

config = ConfigVar.define do
  required_string  :myname
end

puts "hello, world!"

こんな感じです。

$ruby hello.rb
/usr/local/lib/ruby/gems/2.2.0/gems/configvar-0.1.0/lib/configvar/context.rb:34:in `block in required_string': A value must be provided for MYNAME (ConfigVar::ConfigError)
    from /usr/local/lib/ruby/gems/2.2.0/gems/configvar-0.1.0/lib/configvar/context.rb:141:in `block in define_config'
    from /usr/local/lib/ruby/gems/2.2.0/gems/configvar-0.1.0/lib/configvar/context.rb:12:in `call'
    from /usr/local/lib/ruby/gems/2.2.0/gems/configvar-0.1.0/lib/configvar/context.rb:12:in `block in reload'
    from /usr/local/lib/ruby/gems/2.2.0/gems/configvar-0.1.0/lib/configvar/context.rb:11:in `each_value'
    from /usr/local/lib/ruby/gems/2.2.0/gems/configvar-0.1.0/lib/configvar/context.rb:11:in `reload'
    from /usr/local/lib/ruby/gems/2.2.0/gems/configvar-0.1.0/lib/configvar.rb:23:in `define'
    from config.rb:3:in `<main>'
$export MYNAME='John Doe'
$ruby hello.rb
hello, world!

ひっかかると ConfigVar::ConfigError というエラーが投げられます。

ちなみに、以下のように書き換えると

hello.rb
require "configvar"

config = ConfigVar.define do
  required_int  :myint #required_int は整数かどうかを検証する
end

puts "hello, world!"

こうなります

$export MYINT='John Doe'
$ruby hello.rb
/usr/local/lib/ruby/gems/2.2.0/gems/configvar-0.1.0/lib/configvar/context.rb:120:in `rescue in parse_int': John Doe is not a valid boolean for MYINT (ArgumentError)
    from /usr/local/lib/ruby/gems/2.2.0/gems/configvar-0.1.0/lib/configvar/context.rb:118:in `parse_int'
    from /usr/local/lib/ruby/gems/2.2.0/gems/configvar-0.1.0/lib/configvar/context.rb:43:in `block in required_int'
    from /usr/local/lib/ruby/gems/2.2.0/gems/configvar-0.1.0/lib/configvar/context.rb:141:in `block in define_config'
    from /usr/local/lib/ruby/gems/2.2.0/gems/configvar-0.1.0/lib/configvar/context.rb:12:in `call'
    from /usr/local/lib/ruby/gems/2.2.0/gems/configvar-0.1.0/lib/configvar/context.rb:12:in `block in reload'
    from /usr/local/lib/ruby/gems/2.2.0/gems/configvar-0.1.0/lib/configvar/context.rb:11:in `each_value'
    from /usr/local/lib/ruby/gems/2.2.0/gems/configvar-0.1.0/lib/configvar/context.rb:11:in `reload'
    from /usr/local/lib/ruby/gems/2.2.0/gems/configvar-0.1.0/lib/configvar.rb:23:in `define'
    from hello.rb:3:in `<main>'
$export MYINT=1234
$ruby hello.rb
hello, world!

rails でやってみる

乱暴なんですが、とりあえずこんな感じで。

config/environment_variables.rb
require "configvar"
require "uuid"

config = ConfigVar.define do
  required_custom :uuid do |env|
    value = env['UUID']
    if UUID.validate(value)
      value
    else
      error_message = "A valid value must be provided for ENV['UUID']"
      raise ConfigVar::ConfigError.new(error_message)
    end
  end
end
config/environment.rb
# Load the Rails application.
require_relative 'application'
require_relative 'environment_variables' #追記した
# Initialize the Rails application.
Rails.application.initialize!

この例だと、環境変数 UUIDUUID::validate を通過しない値が設定されていたとき、A valid value must be provided for ENV['UUID'] (ConfigVar::ConfigError) とエラーがでるようになります。

ConfigVar.define のなかが汚くなりそうだったり、なんかもっといい方法ありそうだけど、取り急ぎ〜。

satour
そのへんの文系サラリーマン
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away