Getting a basic response:
response = Faraday.get({url})
Re-use your connection to the same API, while handling different endpoints:
conn = Faraday.new({base url})
response1 = conn.get("/api/v1/thing/1")
data = JSON.parse(response1.body)
response2 = conn.post("api/v1/other-thing", {name: 'John', age: '30'})
data2 = JSON.parse(response2.body)
- Docs
- Used as a specialized browser for making & testing HTTP requests, organizable by collection.
- When consuming an API, it is best to mock the request so that we can save on HTTP requests to different services. This is because some API providers will limit the # of requests to their endpoints in total, or per hour/day.
- Lesson
- Make sure webmock is installed in the Gemfile's
:test
group. Runbundle install
. - Add
require 'webmock/rspec'
tospec_helper.rb
file - Add the
stub_request
and.to_return
methods to your test. Ex:
stub_request(:method, "the API endpoint")
.to_return(status: ###, body: ..., headers: {#optional})
Optionally, add a fixture file andFile.read
it into your test. You can use Postman to get the raw data.
When you run your test, Webmock will give you helpful error messages with the code to add. Usually (though not always) you can copy-paste that code and remove the headers info.
- Docs
- Use VCR to automatically store fixture files inside of named "cassettes".
- Configuration-heavy, but can configure per-block or per-test suite.
- Add
gem "vcr"
to our:test
block in Gemfile, runbundle
. - Add this codeblock to
rails_helper.rb
:
# VCR configuration
VCR.configure do |config|
config.cassette_library_dir = "spec/fixtures/vcr_cassettes"
config.hook_into :webmock
end
- Add either a
:vcr
flag to a test, or set upVCR.use_cassette('name')
to tests that you'll want to use VCR fixture data for.
- If using the
:vcr
flag per-test, add following to config block:
config.configure_rspec_metadata!
- If you are using API keys as part of your requests, remember to put
config.filter_sensitive_data
in the VCR configuration in rails_helper. NOTE -filter_sensitive_data
takes two params: first is what it will turn the second into. Example:
config.filter_sensitive_data("<hidden_key>") { ENV["KEY_TO_FIND_IN_DOCUMENT"] }
- VCR cassettes can expire, where manual fixture files have to be manually deleted. You can do per-cassette expiration, or global in the config block. Per-cassettes will override the global configuration.
# Per-cassette expiration:
VCR.use_cassette('name_of_cassette', re_record_interval: 7.days) do
# test code goes here
end
# Globally, in VCR config block:
config.default_cassette_options = { re_record_interval: 7.days }
- Rules for Developers, by Sandi Metz
- Lesson on Facades, Services, and refactoring
- Four pillars of OOP - which ones are most at play in regard to Facades/Services patterns, and why?
- Inheritance
- Abstraction
- Encapsulation
- Polymorphism