< Return to Blog

Faking APIs in Development and Staging

Having used Webmock and VCR in past projects, there have been times when I'd spawn an instance of Sinatra, just to hit an API end-point, but this is certainly a better way to go about it.

module FakeMovieFacts
  class Application < Sinatra::Base
    get "/movies/:movie_name/actors" do
      {
        actors: [
          {
            name: "Actor 1",
            character_played: "Character 1"
          },
          {
            name: "Actor 2",
            character_played: "Character 2"
          }
        ]
      }.to_json
    end
  end
end

Initialize this as a new gem with bundle gem fake_movie_facts and extract FakeMovieFacts::Application (above) into fake_movie_facts/lib/fake_movie_facts/application.rb and add a config.ru file to the root of the repo

# config.ru

$LOAD_PATH << File.expand_path("../lib", __FILE)
require "fake_movie_facts/application"

run FakeMovieFacts::Application

You can either run this locally via the rackup command, or deploy to Heroku. Suppose you want to hit your fake API in development, consider an adapter in your main application

# app/models/movie_database.rb

class MovieDatabase
  cattr_accessor :base_url
  self.base_url = ENV.fetch("MOVIE_FACTS_API_BASE_URL")

  def actors_for(movie:)
    HTTParty.get(self.base_url + "/movies/#{movie.id}/actors", format: :json)
  end
end

Had you spawned the fake API locally, your main app could be booted as $ MOVIE_FACTS_API_BASE_URL=localhost:4567 rails server, or point at the Heroku instance MOVIE_FACTS_API_BASE_URL=http://fake-movie-facts.herokuapp.com.

It's worth reading the full article which considers extra challenges when faking APIs in staging, should the need arise.