Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update middleware docs #1277

Merged
merged 3 commits into from May 2, 2021
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
94 changes: 89 additions & 5 deletions docs/middleware/index.md
Expand Up @@ -7,16 +7,100 @@ next_link: ./list
order: 3
---

Under the hood, Faraday uses a Rack-inspired middleware stack for making
requests. Much of Faraday's power is unlocked with custom middleware. Some
middleware is included with Faraday, and others are in external gems.

Here are some of the features that middleware can provide:

- authentication
- caching responses on disk or in memory
- cookies
- following redirects
- JSON encoding/decoding
- logging
- retrying

To use these great features, create a `Faraday::Connection` with `Faraday.new`
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
f.request :retry # retry transient failures
f.response :follow_redirects # follow redirects
f.response :json # decode response bodies as JSON
end
response = conn.get("http://httpbingo.org/get")
```

### How it Works

A `Faraday::Connection` uses a `Faraday::RackBuilder` to assemble a
Rack-inspired middleware stack for making HTTP requests. Each middleware runs
and passes an Env object around to the next one. After the final middleware has
run, Faraday will return a `Faraday::Response` to the end user.

The order in which middleware is stacked is important. Like with Rack, the first
middleware on the list wraps all others, while the last middleware is the
innermost one. If you want to use a custom [adapter](../adapters), it must
therefore be last.

![Middleware](../assets/img/middleware.png)

The order in which middleware is stacked is important. Like with Rack, the
first middleware on the list wraps all others, while the last middleware is the
innermost one, so that must be the adapter.
### Using Middleware

Calling `use` is the most basic way to add middleware to your stack, but most
middleware is conveniently registered in the `request`, `response` or `adapter`
namespaces. All four methods are equivalent apart from the namespacing.

For example, the `Faraday::Request::UrlEncoded` middleware registers itself in
`Faraday::Request` so it can be added with `request`. These two are equivalent:

```ruby
# add by symbol, lookup from Faraday::Request,
# Faraday::Response and Faraday::Adapter registries
conn = Faraday.new do |f|
f.request :url_encoded
f.response :follow_redirects
f.adapter :httpclient
end
```

or:

olleolleolle marked this conversation as resolved.
Show resolved Hide resolved
```ruby
# identical, but add the class directly instead of using lookups
conn = Faraday.new do |f|
f.use Faraday::Request::UrlEncoded
f.use FaradayMiddleware::FollowRedirects
f.use Faraday::Adapter::HTTPClient
end
```

This is also the place to pass options. For example:

```ruby
conn = Faraday.new do |f|
f.request :retry, max: 10
end
```

### Available Middleware

The [Awesome Faraday](https://github.com/lostisland/awesome-faraday/) project
has a complete list of useful, well-maintained Faraday middleware. Middleware is
often provided by external gems, like the
[faraday-middleware](https://github.com/lostisland/faraday_middleware) gem.

We also have [great documentation](list) for the middleware that ships with
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: does this link work? As a casual reader on my phone, I can't recall if we have a "list" link or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but thank you for asking. I appreciate the attention to detail! I am using jekyll serve --livereload to test. It links to the Available Middleware page.

Faraday.

### Detailed Example

Here's a more realistic example:

```ruby
Faraday.new(...) do |conn|
Expand All @@ -25,7 +109,7 @@ Faraday.new(...) do |conn|
conn.request :url_encoded

# Last middleware must be the adapter:
conn.adapter :net_http
conn.adapter :typhoeus
end
```

Expand All @@ -40,7 +124,7 @@ Swapping middleware means giving the other priority. Specifying the
"Content-Type" for the request is explicitly stating which middleware should
process it.

Examples:
For example:

```ruby
# uploading a file:
Expand Down