Consuming API's the right way.
@vjustov
A little backstory
Enter HER
gem 'her'
# config/initializers/her.rb
Her::API.setup url: "https://api.example.com" do |c|
# Request
c.use Faraday::Request::UrlEncoded
# Response
c.use Her::Middleware::DefaultParseJSON
# Adapter
c.use Faraday::Adapter::NetHttp
end
class User
include Her::Model
end
User.all
# GET "https://api.example.com/users" and return a collection of Users
User.find(1)
# GET "https://api.example.com/users/1" and return a User object
@user = User.create(fullname: "Tobias Fünke")
# POST "https://api.example.com/users" with `fullname=Tobias+Fünke`
# and return the saved User object
@user = User.new(fullname: "Tobias Fünke")
@user.occupation = "actor"
@user.save
# POST "https://api.example.com/users" with `fullname=Tobias+Fünke&occupation=actor`
# and return the saved User object
@user = User.find(1)
@user.fullname = "Lindsay Fünke"
@user.save
# PUT "https://api.example.com/users/1" with `fullname=Lindsay+Fünke`
# and return the updated User object
Her::API.setup url: "https://api.example.com" do |c|
connection.use TokenAuthentication
connection.use Faraday::Request::UrlEncoded
connection.use FaradayMiddleware::Caching, memcache
connection.use APIParser
connection.use FaradayMiddleware::Instrumentation
connection.use Faraday::Adapter::NetHttp
end
API
CLIENT
Business Logic
Caching
Content Negotiation
Authentication
Parsing
HTTP Errors Handling
Statelessness
Business Error Handling
Respect the Status code
http://httpstatusrappers.com/200.html
HTTP Errors Handling
Timeouts
Caching API responses locally
Content Negotiation
Handling Rate-Limits
Response Mapping
ResourceKit
class BookResource < ResourceKit::Resource
resources do
default_handler(410) { |response| fail BookExpiredException }
default_handler(404) { |response| fail RecordNotFoundException }
action :find do
path '/api/v1/books/:id'
handler(200) do |response|
BookMapping.extract_single(response.body, :read)
end
end
end
end
BookResource.new(connection: GoodReadsAPIClient.instance.connection)
Kartographer
class BookMapping
include Kartograph::DSL
kartograph do
mapping Book
property :id, scopes: [:read, :list]
property :name, scopes: [:read, :list, :create]
property :pages_count, scopes: [:read]
property :slug, scopes: [:read]
property :isbn, scopes: [:read, :list]
property :print_date, scopes: [:read]
property :end_date, scopes: [:read]
property :edition, scopes: [:read]
end
end
book = Book.new(name: 'The tales of Bobby Tables')
json_for_create = BookMapping.representation_for(:create, book)
Virtus
class Book
include Virtus.model
attribute :id
attribute :name
attribute :pages_count
attribute :slug
attribute :isbn
attribute :print_date
def in_stock?
Inventory.check?(isbn)
end
end
Bop it
Twist it
Pull it
Wrap it
Consuming api the right way
By Viktor Ml. Justo Vasquez
Consuming api the right way
This is the presentation for the talk given at the Open Saturday on November 15, 2016.
- 1,087