Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/lostisland/faraday-multipart

Perform multipart-post requests using Faraday.
https://github.com/lostisland/faraday-multipart

Last synced: about 22 hours ago
JSON representation

Perform multipart-post requests using Faraday.

Awesome Lists containing this project

README

        

# Faraday Multipart

[![ci](https://github.com/lostisland/faraday-multipart/actions/workflows/ci.yaml/badge.svg)](https://github.com/lostisland/faraday-multipart/actions/workflows/ci.yaml)
[![Gem](https://img.shields.io/gem/v/faraday-multipart.svg?style=flat-square)](https://rubygems.org/gems/faraday-multipart)
[![License](https://img.shields.io/github/license/lostisland/faraday-multipart.svg?style=flat-square)](LICENSE.md)

The `Multipart` middleware converts a `Faraday::Request#body` Hash of key/value pairs into a multipart form request, but
only under these conditions:

* The request's Content-Type is "multipart/form-data"
* Content-Type is unspecified, AND one of the values in the Body responds to
`#content_type`.

Faraday contains a couple helper classes for multipart values:

* `Faraday::Multipart::FilePart` wraps binary file data with a Content-Type. The file data can be specified with a String path to a
local file, or an IO object.
* `Faraday::Multipart::ParamPart` wraps a String value with a Content-Type, and optionally a Content-ID.

## Installation

Add this line to your application's Gemfile:

```ruby
gem 'faraday-multipart'
```

And then execute:

```shell
bundle install
```

Or install it yourself as:

```shell
gem install faraday-multipart
```

## Usage

First of all, you'll need to add the multipart middleware to your Faraday connection:

```ruby
require 'faraday'
require 'faraday/multipart'

conn = Faraday.new(...) do |f|
f.request :multipart, **options
# ...
end
```

If you need to [specify a different content type for the multipart
request](https://www.iana.org/assignments/media-types/media-types.xhtml#multipart),
you can do so by providing the `content_type` option but it must start with
`multipart/`
otherwise it will default to `multipart/form-data`:

```ruby
conn = Faraday.new(...) do |f|
f.request :multipart, content_type: 'multipart/mixed'
# ...
end
```

Payload can be a mix of POST data and multipart values.

```ruby
# regular POST form value
payload = { string: 'value' }

# filename for this value is File.basename(__FILE__)
payload[:file] = Faraday::Multipart::FilePart.new(__FILE__, 'text/x-ruby')

# specify filename because IO object doesn't know it
payload[:file_with_name] = Faraday::Multipart::FilePart.new(
File.open(__FILE__),
'text/x-ruby',
File.basename(__FILE__)
)

# Sets a custom Content-Disposition:
# nil filename still defaults to File.basename(__FILE__)
payload[:file_with_header] = Faraday::Multipart::FilePart.new(
__FILE__,
'text/x-ruby',
nil,
'Content-Disposition' => 'form-data; foo=1'
)

# Upload raw json with content type
payload[:raw_data] = Faraday::Multipart::ParamPart.new(
{ a: 1 }.to_json,
'application/json'
)

# optionally sets Content-ID too
payload[:raw_with_id] = Faraday::Multipart::ParamPart.new(
{ a: 1 }.to_json,
'application/json',
'foo-123'
)

conn.post('/', payload)
```

### Sending an array of documents

Sometimes, the server you're calling will expect an array of documents or other values for the same key.
The `multipart` middleware will automatically handle this scenario for you:

```ruby
payload = {
files: [
Faraday::Multipart::FilePart.new(__FILE__, 'text/x-ruby'),
Faraday::Multipart::FilePart.new(__FILE__, 'text/x-pdf')
],
url: [
'http://mydomain.com/callback1',
'http://mydomain.com/callback2'
]
}

conn.post(url, payload)
#=> POST url[]=http://mydomain.com/callback1&url[]=http://mydomain.com/callback2
#=> and includes both files in the request under the `files[]` name
```

However, by default these will be sent with `files[]` key and the URLs with `url[]`, similarly to arrays in URL parameters.
Some servers (e.g. Mailgun) expect each document to have the same parameter key instead.
You can instruct the `multipart` middleware to do so by providing the `flat_encode` option:

```ruby
require 'faraday'
require 'faraday/multipart'

conn = Faraday.new(...) do |f|
f.request :multipart, flat_encode: true
# ...
end

payload = ... # see example above

conn.post(url, payload)
#=> POST url=http://mydomain.com/callback1&url=http://mydomain.com/callback2
#=> and includes both files in the request under the `files` name
```

This works for both `UploadIO` and normal parameters alike.

## Development

After checking out the repo, run `bin/setup` to install dependencies.

Then, run `bin/test` to run the tests.

To install this gem onto your local machine, run `rake build`.

### Releasing a new version

To release a new version, make a commit with a message such as "Bumped to 0.0.2", and change the _Unreleased_ heading in `CHANGELOG.md` to a heading like "0.0.2 (2022-01-01)", and then use GitHub Releases to author a release. A GitHub Actions workflow then publishes a new gem to [RubyGems.org](https://rubygems.org/gems/faraday-multipart).

## Contributing

Bug reports and pull requests are welcome on [GitHub](https://github.com/lostisland/faraday-multipart).

## License

The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).