module Munson # Faraday::Connection wrapper for making JSON API Requests # # @attr_reader [Faraday::Connection] faraday connection object # @attr_reader [Hash] options class Connection # @private attr_reader :faraday, :options CONNECTION_OPTIONS = [:response_key_format].freeze FARADAY_OPTIONS = [:request, :proxy, :ssl, :builder, :url, :parallel_manager, :params, :headers, :builder_class].freeze # Create a new connection. A connection serves as a thin wrapper around a # a faraday connection that includes two pieces of middleware for handling # JSON API Spec # # @param [Hash] args {Munson::Connection} configuration arguments # @param [Proc] block to yield to Faraday::Connection # @see https://github.com/lostisland/faraday/blob/master/lib/faraday/connection.rb Faraday::Connection # # @example Setting the key format # $my_connection = Munson::Connection.new response_key_format: :dasherize, url: "http://api.example.com" do |c| # c.use Your::Custom::Middleware # end # # $my_connection = Munson::Connection.new response_key_format: :camelize, url: "http://api.example.com" do |c| # c.use Your::Custom::Middleware # end # # @example Creating a new connection # $my_connection = Munson::Connection.new url: "http://api.example.com" do |c| # c.use Your::Custom::Middleware # end # # class User < Munson::Resource # self.type = :users # munson.connection = $my_connection # end def initialize(args, &block) configure(args, &block) end # Clones a connection def clone Connection.new(options.dup, &@block) end # JSON API Spec GET request # # @example making a GET request # @connection.get(path: 'addresses', params: {include: 'user'}, headers: {'X-API-Token' => '2kewl'}) # # @option [Hash,nil] params: nil query params # @option [String] path: nil to GET # @option [Hash] headers: nil HTTP Headers # @return [Faraday::Response] def get(path: nil, params: nil, headers: nil) faraday.get do |request| request.headers.merge!(headers) if headers request.url path.to_s, externalize_keys(params) end end # JSON API Spec POST request # # @option [Hash,nil] body: {} query params # @option [String] path: nil path to GET, defaults to Faraday::Connection url + Agent#type # @option [Hash] headers: nil HTTP Headers # @option [Type] http_method: :post describe http_method: :post # @return [Faraday::Response] def post(body: {}, path: nil, headers: nil, http_method: :post) faraday.send(http_method) do |request| request.headers.merge!(headers) if headers request.url path.to_s request.body = body end end # Configure the connection # # @param [Hash] opts {Munson::Connection} configuration options # @return Faraday::Connection # # @example Setting up the default API connection # Munson::Connection.new url: "http://api.example.com" # # @example A custom middleware added to the default list # class MyTokenAuth < Faraday::Middleware # def call(env) # env[:request_headers]["X-API-Token"] = "SECURE_TOKEN" # @app.call(env) # end # end # # Munson::Connection.new url: "http://api.example.com" do |c| # c.use MyTokenAuth # end def configure(args={}, &block) # Cache these for #clone method @options = args @block = block faraday_options = @options.reject { |key, value| !FARADAY_OPTIONS.include?(key.to_sym) } @faraday = Faraday.new(faraday_options) do |conn| yield conn if block_given? conn.request :"Munson::Middleware::EncodeJsonApi", key_formatter conn.response :"Munson::Middleware::JsonParser", key_formatter conn.adapter Faraday.default_adapter end end (CONNECTION_OPTIONS + FARADAY_OPTIONS).each do |option_writer| class_eval <<-RUBY, __FILE__, __LINE__ + 1 # Set the option value and reconfigure this connection def #{option_writer}=(value) @options[:#{option_writer}] = value configure(@options, &@block) @options[:#{option_writer}] end RUBY end def url faraday.url_prefix.to_s end def response_key_format @options[:response_key_format] end private def key_formatter response_key_format ? Munson::KeyFormatter.new(response_key_format) : nil end private def externalize_keys(value) if response_key_format && value.is_a?(Hash) key_formatter.externalize(value) else value end end end end