Cage
A Faraday Cage for your HTTP Interactions.
What Is It?
One of my favorite utilities for testing my APIs is Rack::Test. However, it gets really offended if you try to use it in an interactive session. I ended up using Faraday and hacked together a set of scripts that made interacting with my APIs easy and fun. I've re-written, cleaned up, and expanded upon these scripts and the result is Cage, a Pry-based console which implements a Rack::Test-like internal Ruby DSL. If you don't like the name, I'm open to suggestions. :D
What Can It Do?
Short Answer: Anything Faraday can do, Cage can do. However, I am attempting to make it natural and easy to use in an interactive manner.
By default, the four HTTP verbs, get
, post
, put
, and delete
, are
available and if you prefer you can use them in SHOUTCASE in order to feel
special about it. Each of these will return a Cage::Response, which is a thin
wrapper around a Faraday::Response that facilitates prettier printing and at the
moment, the type detection and auto-parsing of JSON and XML.
Cage will also keep track of where you're at so you don't have to keep entering the fully-qualified domain name or any prefixes common to all your requests.
For example, if you want to hit version one of the Rubygems.org API just set the domain and prefix.
└─> bundle exec cage
[rubygems.org:]-> set :scheme, :http
=> :http
[rubygems.org:]-> set :domain, "rubygems.org"
=> "rubygems.org"
[rubygems.org:]-> set :prefix, "api/v1/gems"
=> "api/v1/gems"
[rubygems.org:]-> get "rails.json"
=>
Status: 200
Headers:
date: Sat, 28 Jan 2012 06:57:49 GMT
server: Apache/2.2.3 (Red Hat) mod_ssl/2.2.3 OpenSSL/0.9.8e-fips-rhel5 Phusion_Passenger/3.0.11
x-powered-by: Phusion Passenger (mod_rails/mod_rack) 3.0.11
etag: "6bc2525a176ae07870d12b35d6c78dcf"
cache-control: max-age=0, private, must-revalidate
x-ua-compatible: IE=Edge,chrome=1
x-runtime: 0.025598
status: 200
content-length: 1096
connection: close
content-type: application/json; charset=utf-8
Body:
{"name"=>"rails", "downloads"=>7422057, "version"=>"3.2.1", .... }
#<Cage::Response:(http://rubygems.org/api/v1/gems/rails.json)>
[rubygems.org:200]-> get "rails.xml"
=>
Status: 200
Headers:
date: Sat, 28 Jan 2012 06:57:53 GMT
server: Apache/2.2.3 (Red Hat) mod_ssl/2.2.3 OpenSSL/0.9.8e-fips-rhel5 Phusion_Passenger/3.0.11
x-powered-by: Phusion Passenger (mod_rails/mod_rack) 3.0.11
etag: "fd13fd2f31fa180391b2e9a9b3c08b79"
cache-control: max-age=0, private, must-revalidate
x-ua-compatible: IE=Edge,chrome=1
x-runtime: 0.034550
status: 200
content-length: 1915
connection: close
content-type: application/xml; charset=utf-8
Body:
{"rubygem"=>{"name"=>"rails", "downloads"=>7422057, "version"=>"3.2.1", ... }
#<Cage::Response:(http://rubygems.org/api/v1/gems/rails.xml)>
[rubygems.org:200]-> get "wontbethere"
=>
Status: 404
Headers:
date: Sat, 28 Jan 2012 07:43:53 GMT
server: Apache/2.2.3 (Red Hat) mod_ssl/2.2.3 OpenSSL/0.9.8e-fips-rhel5 Phus
x-powered-by: Phusion Passenger (mod_rails/mod_rack) 3.0.11
cache-control: no-cache
x-ua-compatible: IE=Edge,chrome=1
x-runtime: 0.011617
status: 404
vary: Accept-Encoding
content-length: 1053
connection: close
content-type: text/html; charset=utf-8
Body:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
Currently, Cage is attempting to remain feature reduced and free of opinions. I have attempted to include of all elements of the Rack::Test DSL that I wish I'd had when hand-testing my APIs or investigating new ones. If there's something you wish Cage did that is not currently available. Please do File an issue and I will do my best to accomodate your request.
Getting It
Once Cage hits 0.1.0, it will be released as a gem. Then you can install it
globally with gem install cage
. Better still, add it to the Gemfile
of your
project.
group :development do
gem "cage"
end
Using It
Running cage
will begin a console session. Cage is like a specialized IRB, but
for HTTP interactions. Imagine that you are working on an API. [Rack::Test][rt]
is an awesome tool but when you try to use it interactively you get an
interesting display of fireworks(read: stacktraces). Cage is based on a utility
script I wrote while working on a REST API. Some days, you just want to monkey
around with your work.
When you run Cage, you're dropped into a special Pry terminal with HTTP related commands available.
Available Commands
-
HTTP Methods:
-
GET
/get
: url, params, headers -
HEAD
/head
: url, params, headers -
DELETE
/delete
: url, params, headers -
POST
/post
: url, body, headers -
PUT
/put
: url, body, headers -
PATCH
/patch
: url, body, headers
-
-
Cage Methods for Requests
-
basic_auth
: login, pass -
token_auth
: token, options -
add_middleware
: middleware_builder_block
-
-
Anything else Ruby can do...
Configuring It
NOTE Global Configs aren't supported yet. Local configs and specified configs are working.
Cage will look first for a global ~/.cagerc.rb
file, then for a localr
./cagerc.rb
in the working directory. Both are essentially instance_eval'd
into your new Cage console so anything that works in Cage will work in a config.
The global one is run first, so you can overload it with a local config. The
local config is for setting up project defaults, you can even automate your
initial authentication if you want.
Roadmap
-
0.2.0 Write tests for whatever I can. WIP Study Pry's tests and read up on testing apps like this in Build Awesome Command-Line Applications in Ruby
-
0.3.0 Make it easier to send XML, YAML, and JSON formatted bodies.
-
0.4.0 Make some decisions about Auth.