Rspec_api_documentation - yay or nay?
March 28, 2014
Short answer
If you’re not using Rails, probably nay. Unless you like activesupport being loaded in surprising places.
Long answer
Rspecapidocumentation is a cool way of generating an API documentation straight from your acceptance specs. It takes the example requests and presents the params and API output in a nice little HTML format that you can point your API consumers at and pretend it’s documentation.
So, imagine a speced Sinatra API app that looks like that:
# fancy_sinatra_api.rb
class FancyAPI < API
patch '/:id' do
object = FancyObject.find(params[:id])
object.update(params[:fancy_object]
object.to_json
end
end
# fancy_sinatra_api_spec.rb
resource "FancyObject" do
set_app FancyAPI
before { @object = FancyObject.create(default_params) }
patch '/:id' do
example_request 'Updating the object', id: @object.id do
expect(status).to == 200
expect(JSON.parse(response_body)['my_fancy_field']).to == 'fancy value'
end
end
end
It’s all nice and dandy when you run the specs. The output’s perfect, everything passes, so you put it in production. And it breaks.
The reason the specs passed is that rspec_api_documentation
depends on
activesupport, which provides a fancy .to_json
method. In production you don’t
load rspec_api_documentation
, so you don’t load activesupport, so your .to_json
is much less fancy and instead of creating a hash of the object attributes just
calls a to_s
on the object and JSONifies the string it gets. It all results in
your API response looking more like this: #<FancyObject:0x007fc793a13260>
than like that: {"my_fancy_field":"fancy value"}
.
What’s the lesson here?
Well, a bit of everything:
- The less dependencies, the better.
- If you’re writing a testing tool, you shouldn’t be loading frontend helpers.
- Writing documentation is still difficult.
- When in doubt, use
object.method(:to_json).source_location
to figure out what’s going on.
Written by Wojciech Ogrodowczyk who takes photos, climbs mountains, and runs Brains & Beards to help companies deliver better mobile applications faster.