mirror of
https://github.com/lostisland/faraday.git
synced 2025-10-17 00:05:28 -04:00
136 lines
3.8 KiB
Markdown
136 lines
3.8 KiB
Markdown
---
|
|
layout: documentation
|
|
title: "Middleware"
|
|
permalink: /middleware/
|
|
next_name: Available Middleware
|
|
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.
|
|
|
|

|
|
|
|
### 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:
|
|
|
|
```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
|
|
Faraday.
|
|
|
|
### Detailed Example
|
|
|
|
Here's a more realistic example:
|
|
|
|
```ruby
|
|
Faraday.new(...) do |conn|
|
|
# POST/PUT params encoders:
|
|
conn.request :multipart
|
|
conn.request :url_encoded
|
|
|
|
# Last middleware must be the adapter:
|
|
conn.adapter :typhoeus
|
|
end
|
|
```
|
|
|
|
This request middleware setup affects POST/PUT requests in the following way:
|
|
|
|
1. `Request::Multipart` checks for files in the payload, otherwise leaves
|
|
everything untouched;
|
|
2. `Request::UrlEncoded` encodes as "application/x-www-form-urlencoded" if not
|
|
already encoded or of another type
|
|
|
|
Swapping middleware means giving the other priority. Specifying the
|
|
"Content-Type" for the request is explicitly stating which middleware should
|
|
process it.
|
|
|
|
For example:
|
|
|
|
```ruby
|
|
# uploading a file:
|
|
payload[:profile_pic] = Faraday::FilePart.new('/path/to/avatar.jpg', 'image/jpeg')
|
|
|
|
# "Multipart" middleware detects files and encodes with "multipart/form-data":
|
|
conn.put '/profile', payload
|
|
```
|