Faraday HTTP Client Documentation

repository·main·Indexed 27 days ago

https://github.com/lostisland/faraday

Faraday is a flexible HTTP client abstraction library for Ruby (3.0+) that provides a consistent interface over various adapters such as Net::HTTP, Typhoeus, Patron, Excon, and HTTPClient. It features a powerful middleware system for processing request/response cycles, support for parallel requests, streaming responses, and automatic response parsing for JSON, XML, and YAML.

Tokens
27.6K
Snippets
83
Records
128
Agent score
86%

What's inside Faraday

  1. Overview of Faraday HTTP client abstraction

    main
    Faraday is an HTTP client library abstraction layer for Ruby. It provides a common interface over various adapters (such as Net::HTTP, Typhoeus, Patron, Excon, and HTTPClient) and utilizes a Rack-inspired middleware pattern to process the request/response cycle. This allows developers to build sophisticated API clients by abstracting away the underlying HTTP implementation details.
  2. Overview of Faraday HTTP Client

    main

    Faraday is an HTTP client library abstraction layer for Ruby. It provides a common interface over various adapters (such as Net::HTTP, Typhoeus, Patron, Excon, and HTTPClient) and uses a middleware pattern inspired by Rack to process the request/response cycle.

    Key features include:

    • Support for multiple adapters
    • Persistent connections (keep-alive)
    • Parallel requests
    • Automatic response parsing (JSON, XML, YAML)
    • Customization via middleware
    • Streaming responses and file uploads
  3. Understand the Faraday Options refactor (BaseOptions and OptionsLike)

    main

    Faraday is transitioning its options subclasses (like ConnectionOptions, RequestOptions, SSLOptions, etc.) from inheriting from Faraday::Options to a new explicit OOP structure based on Faraday::BaseOptions.

    Key concepts:

    • Faraday::OptionsLike: A marker module used to identify objects that behave like options objects. This allows utilities like Utils.deep_merge! to treat them with the same logic as legacy Options objects.
    • Faraday::BaseOptions: An abstract superclass that provides centralized logic for .from, .update, .merge!, .merge, .deep_dup, .to_hash, and .inspect. It also handles nested coercion via a COERCIONS constant.

    Note: For detached subclasses, legacy ergonomics such as Struct indexing, .fetch, .each_key, and the .options/.memoized macros are being dropped in favor of explicit accessors.

  4. Understand the Faraday Env Object

    main

    Faraday uses an env object to pass data between middleware. This object is initialized at the start of a request and passed down the middleware stack. The adapter executes the HTTP request and populates the response property on the env object, which is then passed back up the middleware stack.

    Key lifecycle behavior:

    • Request phase: Configuration and request properties are available.
    • Response phase: Response properties (like :status and :response_body) are only available after the request has been performed, typically within the on_complete callback of a middleware.
  5. Key features of Faraday

    main

    Faraday provides several built-in capabilities for managing HTTP communication:

    • Multiple Adapters: Use different underlying libraries like Net::HTTP, Typhoeus, Patron, Excon, or HTTPClient through a unified interface.
    • Middleware Support: Customize the request/response cycle using Rack-style middleware.
    • Connection Management: Supports persistent connections (keep-alive).
    • Concurrency: Supports parallel requests.
    • Automatic Parsing: Handles automatic response parsing for JSON, XML, and YAML.
    • Advanced HTTP Operations: Supports streaming responses and file uploads.
  6. Test optional adapter features

    main

    By default, the an adapter test suite only checks for required behavior. If your adapter supports optional Faraday features (like streaming or compression), you can enable specific test expectations by calling the features method before the it_behaves_like 'an adapter' call.

    RSpec.describe Faraday::Adapter::MyAdapter do
      # Use the `features` method to turn on only the ones you know you can support.
      features :request_body_on_query_methods,
               :compression,
               :streaming
    
      # Runs the tests provided by Faraday, according to the features specified above.
      it_behaves_like 'an adapter'
    end
  7. Implement streaming support in a custom Faraday adapter

    main

    To support streaming responses in a custom Faraday adapter, you must check if the user requested streaming via env.stream_response?. If true, use env.stream_response to obtain a callback that allows you to pass data chunks to the user.

    When streaming, the response body is consumed by the callback, so it is recommended to set http_response.body = nil to avoid redundant memory usage. If streaming is not requested, perform the request normally.

    module Faraday
      class Adapter
        class FlorpHttp < Faraday::Adapter
          def call(env)
            super
            if env.stream_response? # check if the user wants to stream the response
              # start a streaming response.
              # on_data is a block that will let users consume the response body
              http_response = env.stream_response do |&on_data|
                # perform the request using FlorpHttp
                # the block will be called for each chunk of data
                FlorpHttp.perform_request(...) do |chunk|
                  on_data.call(chunk)
                end
              end
              # the body is already consumed by the block
              # so it's good practice to set it to nil
              http_response.body = nil
            else
              # perform the request normally, no streaming.
              http_response = FlorpHttp.perform_request(...)
            end
            save_response(env, http_response.status, http_response.body, http_response.headers, http_response.reason_phrase)
          end
        end
      end
    end
  8. Configure Proxy Options in Faraday

    main

    You can configure proxy settings in Faraday either globally for a connection or on a per-request basis. All proxy options are optional.

    Available Proxy Options

    OptionTypeDefaultDescription
    :uriURI, StringnilThe Proxy URL.
    :userStringnilThe Proxy username.
    :passwordStringnilThe Proxy password.

    Global Connection Configuration

    To apply proxy settings to all requests made through a specific connection, pass a :proxy key containing the options to the Faraday.new constructor.

    Per-Request Overrides

    To override the connection's proxy settings for a single request, use req.options.proxy.update within the request block.

    # Proxy options can be passed to the connection constructor and will be applied to all requests.
    proxy_options = {
      uri: 'http://proxy.example.com:8080',
      user: 'username',
      password: 'password'
    }
    
    conn = Faraday.new(proxy: proxy_options) do |faraday|
      # ...
    end
    
    # You can then override them on a per-request basis.
    conn.get('/foo') do |req|
      req.options.proxy.update(uri: 'http://proxy2.example.com:8080')
    end
  9. Use the Faraday Test adapter to mock HTTP requests

    main

    The built-in Faraday Test adapter allows you to define stubbed HTTP requests to mock network services in unit tests. When stubbing a request, the block must return an Array containing three items:

    1. An Integer representing the HTTP status code.
    2. A Hash of HTTP headers.
    3. A String representing the response body.

    You can also stub exceptions by raising them within the stub block.

    conn = Faraday.new do |builder|
      builder.adapter :test do |stub|
        # Stubbing a GET request
        stub.get('/ebi') do |env|
          [
            200,
            { 'Content-Type': 'text/plain' },
            'shrimp'
          ]
        end
    
        # Stubbing an exception
        stub.get('/boom') do
          raise Faraday::ConnectionFailed
        end
      end
    end
  10. Use authentication middleware in Faraday 1.x

    main

    In Faraday 1.x, the middleware usage differs from 2.x. Instead of a single :authorization request type, you use specific methods for different authentication types:

    • Basic Auth: Use conn.request :basic_auth, 'username', 'password'
    • Token Auth: Use conn.request :token_auth, 'authentication-token', **options. The options are automatically converted into key=value format in the header.
    • Generic Auth (Bearer): Use conn.request :authorization, 'Bearer', 'authentication-token'
    # Faraday 1.x Basic Auth
    Faraday.new(...) do |conn|
      conn.request :basic_auth, 'username', 'password'
    end
    
    # Faraday 1.x Token Auth
    Faraday.new(...) do |conn|
      conn.request :token_auth, 'authentication-token', **options
    end
    
    # Faraday 1.x Generic Auth
    Faraday.new(...) do |conn|
      conn.request :authorization, 'Bearer', 'authentication-token'
    end