Selective Proxies
I wanted to test a service following "mock almost nothing" principles with a fully-wired application stack but one of the services connected to a real API endpoint. This is all well and good, but the external API limits the number calls that can be made and running the auto-tests will smash through that limit in short order.
I can easily drop a stub for the external API into the environments but sometimes, especially for end-to-end testing, I actually want to use the real service and want to avoid having to to redploy the entire stack if I can avoid it.
I found the excellent Roda framework which makes knocking up APIs a cinch. Building a quick reverse proxy gem was stupidly quick and easy. With this, I can stub the external and sometimes proxy out to the real thing.
Let's say I want alway want to proxy a GET
request to my/api
, here's how I could do it...
require 'roda'
require 'roda/proxy'
class App < Roda
plugin :proxy,
to: 'https://my.server.com',
path_prefix: '/my/api'
route do |r|
# /my
r.on 'my' do
# /my/api
r.on 'api' do
# GET /my/api/path
r.get do
r.proxy
end
end
end
end
And that's it. But since I've also got access to the request, headers and all, I can exploit that with another method the gem provides. Here, I'll proxy the request if a Proxy-Me
header is sent in the request...
r.proxy_when(r.env['PROXY-ME'] == 'true') do
# This request has not been proxied
response['Content-Type'] = 'application/json'
{hello: 'world').to_json
end
The proxy_when
method will proxy when it's passed true, otherwise it'll execute it's code block like a normal bit of Roda.
I can even through a dice and proxy 50% of the time, even when proxying is enabled...
r.proxy_when(r.env['PROXY-ME'] == 'true', probability: 0.5) do
# maybe I'll proxy, maybe I won't
end
This way I can make sure I'm still getting some contact with the real endpoint but still limit the amount of traffic hitting the real service.
Member discussion