From 08fa7c62c63bd4fcf9490e974c676c325d5383a3 Mon Sep 17 00:00:00 2001 From: Mattia Giuffrida Date: Wed, 29 Dec 2021 16:08:46 +0000 Subject: [PATCH 1/2] * Revamps the "adapters" page to prepare for v2.0 release * Highlight the recommended way to use Faraday in the "usage" page * Explain that adapters now need to be explicitly added to the project * Move documentation on how to build an adapter to a dedicated page * Move adapters documentation to gems READMEs --- docs/adapters/em-http.md | 72 ----------- docs/adapters/em-synchrony.md | 78 ------------ docs/adapters/excon.md | 27 ----- docs/adapters/httpclient.md | 30 ----- docs/adapters/index.md | 169 ++------------------------ docs/adapters/net_http.md | 31 ----- docs/adapters/net_http_persistent.md | 29 ----- docs/adapters/patron.md | 29 ----- docs/adapters/write_your_adapter.md | 171 +++++++++++++++++++++++++++ docs/usage/index.md | 129 ++++++++++---------- docs/usage/streaming.md | 6 +- 11 files changed, 253 insertions(+), 518 deletions(-) delete mode 100644 docs/adapters/em-http.md delete mode 100644 docs/adapters/em-synchrony.md delete mode 100644 docs/adapters/excon.md delete mode 100644 docs/adapters/httpclient.md delete mode 100644 docs/adapters/net_http.md delete mode 100644 docs/adapters/net_http_persistent.md delete mode 100644 docs/adapters/patron.md create mode 100644 docs/adapters/write_your_adapter.md diff --git a/docs/adapters/em-http.md b/docs/adapters/em-http.md deleted file mode 100644 index 981bbd95f..000000000 --- a/docs/adapters/em-http.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -layout: documentation -title: "EM-HTTP Adapter" -permalink: /adapters/em-http -hide: true -top_name: Adapters -top_link: ./ ---- - -This Adapter uses [EventMachine](https://github.com/eventmachine/eventmachine/) and the tie in [em-http-request][src] - -It can be used to make parallel requests using EventMachine. - -The major difference between this and EMSynchrony is that it does not use fibers. - -**Error handling and responses have a slightly different behaviour and structure in some cases. Please run thorough testing scenarios, including connection failures and SSL failures** - -You will need to add em-http-request to your Gemfile: - -```ruby -# Gemfile -gem 'em-http-request' -``` - -### Base request -```ruby -require 'faraday' -require 'em-http-request' - -conn = Faraday.new(...) do |f| - # no custom options available - f.adapter :em_http -end -``` - -### Parallel Requests - -```ruby -require 'faraday' -require 'em-http-request' - -urls = Array.new(5) { 'http://127.0.0.1:3000' } - -conn = Faraday::Connection.new do |builder| - builder.adapter :em_http -end - -begin - conn.in_parallel do - puts "Parallel manager: #{conn.parallel_manager}" - - @responses = urls.map do |url| - conn.get(url) - end - end -end - -# Gather responses outside of block -puts @responses.map(&:status).join(', ') -puts @responses.map(&:status).compact.count -``` - -## Links - -* [Gem RDoc][rdoc] -* [Gem source][src] -* [Adapter RDoc][adapter_rdoc] -* [EM-Synchrony Adapter](./em-synchrony.md) - -[rdoc]: https://www.rubydoc.info/gems/em-http-request -[src]: https://github.com/igrigorik/em-http-request#readme -[adapter_rdoc]: https://www.rubydoc.info/github/lostisland/faraday/Faraday/Adapter/EMHttp diff --git a/docs/adapters/em-synchrony.md b/docs/adapters/em-synchrony.md deleted file mode 100644 index e66977575..000000000 --- a/docs/adapters/em-synchrony.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -layout: documentation -title: "EM-Synchrony Adapter" -permalink: /adapters/em-synchrony -hide: true -top_name: Adapters -top_link: ./ ---- - -This Adapter uses [EventMachine](https://github.com/eventmachine/eventmachine/) and the tie in [em-http-request](https://www.rubydoc.info/gems/em-http-request) in conjunction with [em-synchrony][rdoc] - -It can be used to make parallel requests using EventMachine. - -The key difference between this and EM-Http is that it uses fibers. For more information see igrigorik's blog posts on the matter: - -- [fibers-cooperative-scheduling-in-ruby](https://www.igvita.com/2009/05/13/fibers-cooperative-scheduling-in-ruby/) -- [untangling-evented-code-with-ruby-fibers](https://www.igvita.com/2010/03/22/untangling-evented-code-with-ruby-fibers) - -**Error handling and responses have a slightly different behaviour and structure in some cases. Please run thorough testing scenarios, including connection failures and SSL failures** - -You will need to add em-http-request and em-synchrony to your Gemfile: - -```ruby -# Gemfile -gem 'em-http-request' -gem 'em-synchrony' -``` - -### Base request -```ruby -require 'faraday' -require 'em-http-request' -require 'em-synchrony' - -conn = Faraday.new(...) do |f| - # no custom options available - f.adapter :em_synchrony -end -``` - -### Parallel Requests - -```ruby -require 'faraday' -require 'em-http-request' -require 'em-synchrony' - -urls = Array.new(5) { 'http://127.0.0.1:3000' } - -conn = Faraday::Connection.new do |builder| - builder.adapter :em_synchrony -end - -begin - conn.in_parallel do - puts "Parallel manager: #{conn.parallel_manager}" - - @responses = urls.map do |url| - conn.get(url) - end - end -end - -# Gather responses outside of block -puts @responses.map(&:status).join(', ') -puts @responses.map(&:status).compact.count -``` - -## Links - -* [Gem RDoc][rdoc] -* [Gem source][src] -* [Adapter RDoc][adapter_rdoc] -* [EM-HTTP Adapter](./em-http.md) - -[rdoc]: https://www.rubydoc.info/gems/em-synchrony -[src]: https://github.com/igrigorik/em-synchrony -[adapter_rdoc]: https://www.rubydoc.info/github/lostisland/faraday/Faraday/Adapter/EMSynchrony diff --git a/docs/adapters/excon.md b/docs/adapters/excon.md deleted file mode 100644 index 270a8e122..000000000 --- a/docs/adapters/excon.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -layout: documentation -title: "Excon Adapter" -permalink: /adapters/excon -hide: true -top_name: Adapters -top_link: ./ ---- - -This Adapter uses the [excon][rdoc] gem to make HTTP requests. - -```ruby -conn = Faraday.new(...) do |f| - # no custom options available - f.adapter :excon -end -``` - -## Links - -* [Gem RDoc][rdoc] -* [Gem source][src] -* [Adapter RDoc][adapter_rdoc] - -[rdoc]: https://www.rubydoc.info/gems/excon -[src]: https://github.com/excon/excon -[adapter_rdoc]: https://www.rubydoc.info/github/lostisland/faraday/Faraday/Adapter/Excon diff --git a/docs/adapters/httpclient.md b/docs/adapters/httpclient.md deleted file mode 100644 index 9d711498c..000000000 --- a/docs/adapters/httpclient.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -layout: documentation -title: "HTTPClient Adapter" -permalink: /adapters/httpclient -hide: true -top_name: Adapters -top_link: ./ ---- - -This Adapter uses the [httpclient][rdoc] gem to make HTTP requests. - -```ruby -conn = Faraday.new(...) do |f| - f.adapter :httpclient do |client| - # yields HTTPClient - client.keep_alive_timeout = 20 - client.ssl_config.timeout = 25 - end -end -``` - -## Links - -* [Gem RDoc][rdoc] -* [Gem source][src] -* [Adapter RDoc][adapter_rdoc] - -[rdoc]: https://www.rubydoc.info/gems/httpclient -[src]: https://github.com/nahi/httpclient -[adapter_rdoc]: https://www.rubydoc.info/github/lostisland/faraday/Faraday/Adapter/HTTPClient diff --git a/docs/adapters/index.md b/docs/adapters/index.md index 6b43619f4..e92960d6d 100644 --- a/docs/adapters/index.md +++ b/docs/adapters/index.md @@ -11,32 +11,17 @@ HTTP clients, but can have custom implementations. Adapters can be configured either globally or per Faraday Connection through the configuration block. {: .mt-60} -## Built-in adapters +## Fantastic adapters and where to find them -Faraday includes these adapters (but not the HTTP client libraries): - -* [Net::HTTP][net_http] _(this is the default adapter)_ -* [Net::HTTP::Persistent][persistent] -* [Excon][excon] -* [Patron][patron] -* [EM-Synchrony][em-synchrony] -* [EM-Http][em-http] -* [HTTPClient][httpclient] +With the only exception being the [Test Adapter][testing], which is for _test purposes only_, +adapters are distributed separately from Faraday. +They are usually available as gems, or bundled with HTTP clients. While most adapters use a common Ruby HTTP client library, adapters can also have completely custom implementations. -* [Test Adapter][testing] -* Rack Adapter (link TBD) - -## External adapters - -Adapters are slowly being moved into their own gems, or bundled with HTTP clients. -Please refer to their documentation for usage examples. - -* [Typhoeus][typhoeus] -* [HTTP.rb][faraday-http] -* [httpx][httpx] +If you're just getting started you can find a list of featured adapters in [Awesome Faraday][awesome]. +Anyone can create a Faraday adapter and distribute it. If you're interested learning more, check how to [build your own][build_adapters]! ## Ad-hoc adapters customization @@ -45,142 +30,6 @@ However, sometimes you need to access a feature specific to one of the adapters When that happens, you can pass a block when specifying the adapter to customize it. The block parameter will change based on the adapter you're using. See each adapter page for more details. -## Write your own adapter - -Adapters have methods that can help you implement support for a new backend. - -This example will use a fictional HTTP backend gem called `FlorpHttp`. It doesn't -exist. Its only function is to make this example more concrete. - -### An Adapter _is_ a Middleware - -When you subclass `::Faraday::Adapter`, you get helpful methods defined: - -```ruby -class FlorpHttp < ::Faraday::Adapter -end -``` - -Now, there are only two things which are actually mandatory for an adapter middleware to function: - -- a `#call` implementation -- a call to `#save_response` inside `#call`, which will keep the Response around. - -These are the only two things. - -The rest of this text is about methods which make the authoring easier. - -### Helpful method: `#build_connection` - -Faraday abstracts all your backend's concrete stuff behind its user-facing API. -You take care of setting up the connection from the supplied parameters. - -Example from the excon adapter: it gets an `Env` and reads its information -to instantiate an `Excon` object: - -```ruby -class FlorpHttp < ::Faraday::Adapter - def build_connection(env) - opts = opts_from_env(env) - ::Excon.new(env[:url].to_s, opts.merge(@connection_options)) - end -end -``` - -The `env` contains stuff like: - -- `env[:ssl]` -- `env[:request]` - -There are helper to fetch timeouts: `#request_timeout(type, options)` knows -about supported timeout types, and falls back to `:timeout` if they are not set. -You can use those when building the options you need for your backend's instantiation. - -So, use the information provided in `env` to instantiate your backend's connection class. -Return that instance. Now, Faraday knows how to create and reuse that connection. - -### Nickname for your adapter: `.register_middleware` - -You may register a nickname for your adapter. People can then refer to your adapter with that name. -You do that using `.register_middleware`, like this: - -```ruby -class FlorpHttp < ::Faraday::Adapter - register_middleware( - File.expand_path('adapter', __dir__), - florp_http: [ :FlorpHttp, 'florp_http' ] - ) - # ... -end -``` - -## Does your backend support parallel operation? - -:warning: This is slightly more involved, and this section is not fully formed. - -Vague example, excerpted from [the test suite about parallel requests](https://github.com/lostisland/faraday/blob/master/spec/support/shared_examples/request_method.rb#L179) - -```ruby -response_1 = nil -response_2 = nil - -conn.in_parallel do - response_1 = conn.get('/about') - response_2 = conn.get('/products') -end - -puts response_1.status -puts response_2.status -``` - -First, in your class definition, you can tell Faraday that your backend supports parallel operation: - -```ruby -class FlorpHttp < ::Faraday::Adapter - dependency do - require 'florp_http' - end - - self.supports_parallel = true -end -``` - -Then, implement a method which returns a ParallelManager: - -```ruby -class FlorpHttp < ::Faraday::Adapter - dependency do - require 'florp_http' - end - - self.supports_parallel = true - - def self.setup_parallel_manager(_options = nil) - FlorpParallelManager.new # NB: we will need to define this - end -end - -class FlorpParallelManager - def add(request, method, *args, &block) - # Collect the requests - end - - def run - # Process the requests - end -end -``` - -Compare to the finished example [em-synchrony](https://github.com/lostisland/faraday/blob/master/lib/faraday/adapter/em_synchrony.rb) and its [ParallelManager implementation](https://github.com/lostisland/faraday/blob/master/lib/faraday/adapter/em_synchrony/parallel_manager.rb). - -[net_http]: ./net-http -[persistent]: ./net-http-persistent -[excon]: ./excon -[patron]: ./patron -[em-synchrony]: ./em-synchrony -[em-http]: ./em-http -[httpclient]: ./httpclient -[typhoeus]: https://github.com/typhoeus/typhoeus/blob/master/lib/typhoeus/adapters/faraday.rb -[faraday-http]: https://github.com/lostisland/faraday-http -[testing]: ./testing -[httpx]: https://honeyryderchuck.gitlab.io/httpx/wiki/Faraday-Adapter +[testing]: ./testing +[awesome]: https://github.com/lostisland/awesome-faraday/#adapters +[build_adapters]: ./write_your_adapter.md diff --git a/docs/adapters/net_http.md b/docs/adapters/net_http.md deleted file mode 100644 index e1890b3bb..000000000 --- a/docs/adapters/net_http.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -layout: documentation -title: "Net::HTTP Adapter" -permalink: /adapters/net-http -hide: true -top_name: Adapters -top_link: ./ ---- - -This Adapter uses the [`Net::HTTP`][rdoc] client from the Ruby standard library to make -HTTP requests. - -```ruby -conn = Faraday.new(...) do |f| - f.adapter :net_http do |http| - # yields Net::HTTP - http.idle_timeout = 100 - http.verify_callback = lambda do |preverify, cert_store| - # do something here... - end - end -end -``` - -## Links - -* [Net::HTTP RDoc][rdoc] -* [Adapter RDoc][adapter_rdoc] - -[rdoc]: http://ruby-doc.org/stdlib/libdoc/net/http/rdoc/Net/HTTP.html -[adapter_rdoc]: https://www.rubydoc.info/github/lostisland/faraday/Faraday/Adapter/NetHttp diff --git a/docs/adapters/net_http_persistent.md b/docs/adapters/net_http_persistent.md deleted file mode 100644 index 4c563e6ef..000000000 --- a/docs/adapters/net_http_persistent.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -layout: documentation -title: "Net::HTTP::Persistent Adapter" -permalink: /adapters/net-http-persistent -hide: true -top_name: Adapters -top_link: ./ ---- - -This Adapter uses the [net-http-persistent][rdoc] gem to make HTTP requests. - -```ruby -conn = Faraday.new(...) do |f| - f.adapter :net_http_persistent, pool_size: 5 do |http| - # yields Net::HTTP::Persistent - http.idle_timeout = 100 - end -end -``` - -## Links - -* [Gem RDoc][rdoc] -* [Gem source][src] -* [Adapter RDoc][adapter_rdoc] - -[rdoc]: https://www.rubydoc.info/gems/net-http-persistent -[src]: https://github.com/drbrain/net-http-persistent -[adapter_rdoc]: https://www.rubydoc.info/github/lostisland/faraday/Faraday/Adapter/NetHttpPersistent diff --git a/docs/adapters/patron.md b/docs/adapters/patron.md deleted file mode 100644 index a6ec1eec3..000000000 --- a/docs/adapters/patron.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -layout: documentation -title: "Patron Adapter" -permalink: /adapters/patron -hide: true -top_name: Adapters -top_link: ./ ---- - -This Adapter uses the [patron][rdoc] gem to make HTTP requests. - -```ruby -conn = Faraday.new(...) do |f| - f.adapter :patron do |session| - # yields Patron::Session - session.max_redirects = 10 - end -end -``` - -## Links - -* [Gem RDoc][rdoc] -* [Gem source][src] -* [Adapter RDoc][adapter_rdoc] - -[rdoc]: https://www.rubydoc.info/gems/patron -[src]: https://github.com/toland/patron -[adapter_rdoc]: https://www.rubydoc.info/github/lostisland/faraday/Faraday/Adapter/Patron diff --git a/docs/adapters/write_your_adapter.md b/docs/adapters/write_your_adapter.md new file mode 100644 index 000000000..bc8ec851d --- /dev/null +++ b/docs/adapters/write_your_adapter.md @@ -0,0 +1,171 @@ +--- +layout: documentation +title: "Write your own adapter" +permalink: /adapters/write_your_adapter +hide: true +order: 2 +--- + +Adapters have methods that can help you implement support for a new backend. + +This example will use a fictional HTTP backend gem called `FlorpHttp`. It doesn't +exist. Its only function is to make this example more concrete. + +### An Adapter _is_ a Middleware + +When you subclass `::Faraday::Adapter`, you get helpful methods defined: + +```ruby +class FlorpHttp < ::Faraday::Adapter +end +``` + +Now, there are only two things which are actually mandatory for an adapter middleware to function: + +- a `#call` implementation +- a call to `#save_response` inside `#call`, which will keep the Response around. + +These are the only two things. +The rest of this text is about methods which make the authoring easier. + +### Helpful method: `#build_connection` + +Faraday abstracts all your backend's concrete stuff behind its user-facing API. +You take care of setting up the connection from the supplied parameters. + +Example from the excon adapter: it gets an `Env` and reads its information +to instantiate an `Excon` object: + +```ruby +class FlorpHttp < ::Faraday::Adapter + def build_connection(env) + opts = opts_from_env(env) + ::Excon.new(env[:url].to_s, opts.merge(@connection_options)) + end +end +``` + +The `env` contains stuff like: + +- `env[:ssl]` +- `env[:request]` + +There are helper to fetch timeouts: `#request_timeout(type, options)` knows +about supported timeout types, and falls back to `:timeout` if they are not set. +You can use those when building the options you need for your backend's instantiation. + +So, use the information provided in `env` to instantiate your backend's connection class. +Return that instance. Now, Faraday knows how to create and reuse that connection. + +### Connection options and configuration block + +Users of your adapter have two main ways of configuring it: +* connection options: these can be passed to your adapter initializer and are automatically stored into an instance variable `@connection_options`. +* configuration block: this can also be provided to your adapter initializer and it's stored into an instance variable `@config_block`. + +Both of these are automatically managed by `Faraday::Adapter#initialize`, so remember to call it with `super` if you create an `initialize` method in your adapter. +You can then use them in your adapter code as you wish, since they're pretty flexible. + +Below is an example of how they can be used: + +```ruby +# You can use @connection_options and @config_block in your adapter code +class FlorpHttp < ::Faraday::Adapter + def call(env) + # `connection` internally calls `build_connection` and yields the result + connection do |conn| + # perform the request using configured `conn` + end + end + + def build_connection(env) + conn = FlorpHttp::Client.new(pool_size: @connection_options[:pool_size] || 10) + @config_block&.call(conn) + conn + end +end + +# Then your users can provide them when initializing the connection +Faraday.new(...) do |f| + # ... + # in this example, { pool_size: 5 } will be provided as `connection_options` + f.adapter :florp_http, pool_size: 5 do |client| + # this block is useful to set properties unique to HTTP clients that are not + # manageable through the Faraday API + client.some_fancy_florp_http_property = 10 + end +end +``` + +### Nickname for your adapter: `.register_middleware` + +You may register a nickname for your adapter. People can then refer to your adapter with that name. +You do that using `.register_middleware`, like this: + +```ruby +class FlorpHttp < ::Faraday::Adapter + # ... +end + +Faraday::Adapter.register_middleware(florp_http: FlorpHttp) +``` + +## Does your backend support parallel operation? + +:warning: This is slightly more involved, and this section is not fully formed. + +Vague example, excerpted from [the test suite about parallel requests](https://github.com/lostisland/faraday/blob/master/spec/support/shared_examples/request_method.rb#L179) + +```ruby +response_1 = nil +response_2 = nil + +conn.in_parallel do + response_1 = conn.get('/about') + response_2 = conn.get('/products') +end + +puts response_1.status +puts response_2.status +``` + +First, in your class definition, you can tell Faraday that your backend supports parallel operation: + +```ruby +class FlorpHttp < ::Faraday::Adapter + dependency do + require 'florp_http' + end + + self.supports_parallel = true +end +``` + +Then, implement a method which returns a ParallelManager: + +```ruby +class FlorpHttp < ::Faraday::Adapter + dependency do + require 'florp_http' + end + + self.supports_parallel = true + + def self.setup_parallel_manager(_options = nil) + FlorpParallelManager.new # NB: we will need to define this + end +end + +class FlorpParallelManager + def add(request, method, *args, &block) + # Collect the requests + end + + def run + # Process the requests + end +end +``` + +Compare to the finished example [em-synchrony](https://github.com/lostisland/faraday-em_synchrony/blob/main/lib/faraday/adapter/em_synchrony.rb) +and its [ParallelManager implementation](https://github.com/lostisland/faraday-em_synchrony/blob/main/lib/faraday/adapter/em_synchrony/parallel_manager.rb). diff --git a/docs/usage/index.md b/docs/usage/index.md index 238522278..c65852b0b 100644 --- a/docs/usage/index.md +++ b/docs/usage/index.md @@ -8,17 +8,29 @@ order: 1 --- Let's fetch the home page for the wonderful -[httpbingo.org](https://httpbingo.org) service. Make a simple `GET` request by -requiring the Faraday gem and using `Faraday.get`: +[httpbingo.org](https://httpbingo.org) service. + +First of all, you need to tell Faraday which [`adapter`](../adapters) you wish to use. +Adapters are responsible for actually executing HTTP requests. +There are many different adapters you can choose from. +Just pick the one you like and install it, or add it to your project Gemfile. +You might want to use Faraday with the `Net::HTTP` adapter, for example. +[Learn more about Adapters](../adapters). + +Remember you'll need to install the corresponding adapter gem before you'll be able to use it. ```ruby -require 'faraday' +require 'faraday/net_http' +Faraday.default_adapter = :net_http +``` -response = Faraday.get 'http://httpbingo.org' +Next, you can make a simple `GET` request using `Faraday.get`: + +```ruby +response = Faraday.get('http://httpbingo.org') ``` -This returns a `Faraday::Response` object with the response status, headers, and -body. +This returns a `Faraday::Response` object with the response status, headers, and body. ```ruby response.status @@ -31,10 +43,36 @@ response.body # => " ... ``` -### GET +### Faraday Connection + +The recommended way to use Faraday, especially when integrating to 3rd party services and API, is to create +a `Faraday::Connection`. The connection object can be configured with things like: + +- default request headers & query parameters +- network settings like proxy or timeout +- common URL base path +- Faraday adapter & middleware (see below) + +Create a `Faraday::Connection` by calling `Faraday.new`. You can then call each HTTP verb +(`get`, `post`, ...) on your `Faraday::Connection` to perform a request: + +```ruby +conn = Faraday.new( + url: 'http://httpbingo.org', + params: {param: '1'}, + headers: {'Content-Type' => 'application/json'} +) + +response = conn.post('/post') do |req| + req.params['limit'] = 100 + req.body = {query: 'chunky bacon'}.to_json +end +# => POST http://httpbingo.org/post?param=1&limit=100 +``` + +### GET, HEAD, DELETE, TRACE -Faraday supports the following HTTP verbs that typically don't include a request -body: +Faraday supports the following HTTP verbs that typically don't include a request body: - `get(url, params = nil, headers = nil)` - `head(url, params = nil, headers = nil)` @@ -44,12 +82,11 @@ body: You can specify URI query parameters and HTTP headers when making a request. ```ruby -url = 'http://httpbingo.org/get' -response = Faraday.get(url, {boom: 'zap'}, {'User-Agent' => 'myapp'}) +response = conn.get('get', { boom: 'zap' }, { 'User-Agent' => 'myapp' }) # => GET http://httpbingo.org/get?boom=zap ``` -### POST +### POST, PUT, PATCH Faraday also supports HTTP verbs with bodies. Instead of query parameters, these accept a request body: @@ -59,13 +96,11 @@ accept a request body: - `patch(url, body = nil, headers = nil)` ```ruby -url = 'http://httpbingo.org/post' - # POST 'application/x-www-form-urlencoded' content -response = Faraday.post(url, "boom=zap") +response = conn.post('post', 'boom=zap') # POST JSON content -response = Faraday.post(url, '{"boom": "zap"}', +response = conn.post('post', '{"boom": "zap"}', "Content-Type" => "application/json") ``` @@ -75,8 +110,7 @@ Faraday will automatically convert key/value hashes into proper form bodies. ```ruby # POST 'application/x-www-form-urlencoded' content -url = 'http://httpbingo.org/post' -response = Faraday.post(url, boom: 'zap') +response = conn.post('post', boom: 'zap') # => POST 'boom=zap' to http://httpbingo.org/post ``` @@ -93,7 +127,7 @@ This example shows a hypothetical search endpoint that accepts a JSON request body as the actual search query. ```ruby -response = Faraday.post('http://httpbingo.org/post') do |req| +response = conn.post('post') do |req| req.params['limit'] = 100 req.headers['Content-Type'] = 'application/json' req.body = {query: 'chunky bacon'}.to_json @@ -101,40 +135,6 @@ end # => POST http://httpbingo.org/post?limit=100 ``` -### Customizing Faraday::Connection - -You may want to create a `Faraday::Connection` to setup a common config for -multiple requests. The connection object can be configured with things like: - -- default request headers & query parameters -- network settings like proxy or timeout -- common URL base path -- Faraday adapter & middleware (see below) - -Create a `Faraday::Connection` by calling `Faraday.new`. The HTTP verbs -described above (`get`, `post`, ...) are `Faraday::Connection` methods: - -```ruby -conn = Faraday.new( - url: 'http://httpbingo.org', - params: {param: '1'}, - headers: {'Content-Type' => 'application/json'} -) - -response = conn.post('/post') do |req| - req.params['limit'] = 100 - req.body = {query: 'chunky bacon'}.to_json -end -# => POST http://httpbingo.org/post?param=1&limit=100 -``` - -### Adapters - -Adapters are responsible for actually executing HTTP requests. The default -adapter uses Ruby's `Net::HTTP`, but there are many different adapters -available. You might want to use Faraday with the Typhoeus adapter, for example. -[Learn more about Adapters](../adapters). - ### Middleware Under the hood, Faraday uses a Rack-inspired middleware stack for making @@ -158,13 +158,20 @@ and add the correct middleware in a block. For example: ```ruby require 'faraday_middleware' -conn = Faraday.new do |f| - f.request :json # encode req bodies as JSON +conn = Faraday.new('http://httpbingo.org') do |f| + f.request :json # encode req bodies as JSON and automatically set the Content-Type header f.request :retry # retry transient failures - f.response :follow_redirects # follow redirects + f.response :follow_redirects # follow redirects (3xx HTTP response codes) f.response :json # decode response bodies as JSON + f.adapter :net_http # adds the adapter to the connection, defaults to `Faraday.default_adapter` end -response = conn.get("http://httpbingo.org/get") + +# Sends a GET request with JSON body that will automatically retry in case of failure +# and follow 3xx redirects. +response = conn.get('get', boom: 'zap') + +# response body is automatically decoded from JSON to a Ruby hash +response.body['args'] #=> {"boom"=>["zap"]} ``` #### Default Connection, Default Middleware @@ -173,10 +180,10 @@ Remember how we said that Faraday will automatically encode key/value hash bodies into form bodies? Internally, the top level shortcut methods `Faraday.get`, `post`, etc. use a simple default `Faraday::Connection`. The only middleware used for the default connection is `:url_encoded`, which encodes -those form hashes. +those form hashes, and the `default_adapter`. Note that if you create your own connection with middleware, it won't encode -form bodies unless you too include the `:url_encoded` middleware! +form bodies unless you too include the [`:url_encoded`](encoding) middleware! -[encoding]: ../middleware/url-encoded -[multipart]: ../middleware/multipart +[encoding]: ../middleware/url-encoded +[multipart]: ../middleware/multipart diff --git a/docs/usage/streaming.md b/docs/usage/streaming.md index 24df5255b..26a3d3371 100644 --- a/docs/usage/streaming.md +++ b/docs/usage/streaming.md @@ -34,4 +34,8 @@ end streamed.join ``` -The `on_data` streaming is currently only supported by the `Net::HTTP` adapter. +The `on_data` streaming is currently only supported by some adapters. +To see which ones, please refer to [Awesome Faraday][awesome] comparative table or check the adapter documentation. + +[awesome]: https://github.com/lostisland/awesome-faraday/#adapters + From 78e47f78c6b4a718863b4e5f070c7401c4058f01 Mon Sep 17 00:00:00 2001 From: Matt Date: Thu, 30 Dec 2021 14:22:03 +0000 Subject: [PATCH 2/2] Code Review comment: Fix typo --- docs/adapters/write_your_adapter.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/adapters/write_your_adapter.md b/docs/adapters/write_your_adapter.md index bc8ec851d..a9075d894 100644 --- a/docs/adapters/write_your_adapter.md +++ b/docs/adapters/write_your_adapter.md @@ -50,7 +50,7 @@ The `env` contains stuff like: - `env[:ssl]` - `env[:request]` -There are helper to fetch timeouts: `#request_timeout(type, options)` knows +There are helper methods to fetch timeouts: `#request_timeout(type, options)` knows about supported timeout types, and falls back to `:timeout` if they are not set. You can use those when building the options you need for your backend's instantiation.