Para o meu gem de sistema de gerenciamento de conteúdo http://Home-Page.Software, eu queria oferecer suporte a diferentes APIs e usar o host certo para o ambiente atual por uma cadeia de fallback.
Portanto, preciso lidar com aliases de nomes de ambiente de usuário e ambientes não suportados por um provedor de API.
Dadas essas configurações de um inicializador Rails alimentado por rails-settings-cached (você tem que usar desenvolvimento, teste, teste ou produção como chave):
Setting.defaults[
'apis.providers.volontariat.hosts.development'
] = 'http://localhost:3001'
Setting.defaults[
'apis.providers.volontariat.hosts.production'
] = 'http://Volontari.at' # currently down :-(
Eu queria algo assim:
host = ApiProviderHost.new('volontariat', Rails.env).to_s
Espero que se comporte assim:
describe ApiProviderHost do
describe '#to_s' do
it 'behaves like this' do
provider = 'name_of_host'
Setting.defaults[
'apis.providers.name_of_host.hosts.development'
] = 'http://localhost:3001'
# no fallback or alias mapping needed
expect(
described_class.new(provider, 'development').to_s
).to be == 'http://localhost:3001'
# fallback to development
expect(
described_class.new(provider, 'test').to_s
).to be == 'http://localhost:3001'
# alias mapping needed
expect(
described_class.new(provider, 'dev').to_s
).to be == 'http://localhost:3001'
# alias not found
expect{
described_class.new(provider, 'unknown_environment').to_s
}.to raise_error(
NotImplementedError,
'Your environment is unknown. Please update alias mapping!'
)
# environment not supported by provider
expect{
described_class.new(provider, 'staging').to_s
}.to raise_error(
NotImplementedError,
'The API provider does not support your environment!'
)
end
end
end
E eu implementei esta aula:
class ApiProviderHost
ENVIRONMENTS = [:development, :test, :staging, :production]
ALIASES = {
dev: :development, testing: :test, stage: :staging, show: :staging,
live: :production, prod: :production
}
FALLBACKS = {
development: [:development, :test, :staging, :production],
test: [:test, :development, :staging, :production],
staging: [:staging, :production],
production: [:production]
}
def initialize(provider, working_environment)
@provider = provider
@environment = working_environment.to_s.to_sym
end
def setting_namespace
"apis.providers.#{@provider}.hosts"
end
def environment
if ENVIRONMENTS.include?(@environment)
@environment
else
ALIASES[@environment] || raise(
NotImplementedError,
'Your environment is unknown. Please update alias mapping!'
)
end
end
def to_s
host = nil
FALLBACKS[environment].each do |provider_environment|
host = Setting["#{setting_namespace}.#{provider_environment}"]
break if host
end
unless host
raise(
NotImplementedError,
'The API provider does not support your environment!'
)
end
host
end
end
PS: No passado eu vivia sempre configurando um host para cada ambiente e sem mapeamento de alias de ambiente, mas isso não era SECO :
Setting.defaults[
'apis.providers.volontariat.hosts.development'
] = 'http://localhost:3001'
Setting.defaults[
'apis.providers.volontariat.hosts.test'
] = 'http://localhost:3001'
Setting.defaults[
'apis.providers.volontariat.hosts.staging'
] = 'http://Volontari.at'
Setting.defaults[
'apis.providers.volontariat.hosts.production'
] = 'http://Volontari.at'
# optional: I also put the little envionment alias mapping code here if you can't live without it
environment = {
dev: :development, testing: :test, stage: :staging, show: :staging,
live: :production, prod: :production
}[Rails.env.to_s.to_sym] || Rails.env
host = Setting[
"apis.providers.volontariat.hosts.#{environment}"
]