# FormData
A library for formatting data to be used with
[HTTPoison](https://github.com/edgurgel/httpoison) and
[Hackney](https://github.com/benoitc/hackney).
This library was originally written to help with formatting data to upload files
for internal Spiceworks projects, but has expanded to include formatting all
`multipart` data for `POST` requests to work with `HTTPoison` and `Hackney`, in
addition to formatting `url encoded` requests for `POST` and `GET`, both with
the supported `HTTPoison` syntax and with a string to append to any URL.
## Installation
Add `httpoison_form_data` to your list of dependencies in `mix.exs`:
```elixir
def application do
[applications: [:httpoison]]
end
def deps do
[{:httpoison_form_data, "~> 0.1"},
{:httpoison, "~> 1.0"}]
end
```
## Usage
The outermost layer in your nested structure MUST be a map, keyword list, or struct.
## Multipart Requests
```elixir
# This structure will be used in the following example
some_structure = %{
first_key: "first_value",
second_key: [
"second_value",
"third_value",
%{
third_key: "fourth_value",
fourth_key: {
"fifth_value",
"sixth_value"
}
}
],
fifth_key: FormData.File.new("path/to/file.txt")
}
```
#### Example 1
```elixir
with {:ok, payload} <- FormData.create(some_structure, :multipart),
do: HTTPoison.post("some.url/", payload)
# The above code produces the following request
HTTPoison.post("some.url/", {
:multipart,
[
{"", "first_value", {"form-data", [{"name", "\"first_key\""}]}, []},
{"", "second_value", {"form-data", [{"name", "\"second_key[]\""}]}, []},
{"", "third_value", {"form-data", [{"name", "\"second_key[]\""}]}, []},
{"", "fourth_value", {"form-data", [{"name", "\"second_key[][third_key]\""}]}, []},
{"", "fifth_value", {"form-data", [{"name", "\"second_key[][fourth_key][]\""}]}, []},
{"", "sixth_value", {"form-data", [{"name", "\"second_key[][fourth_key][]\""}]}, []},
{:file, "path/to/file.txt", {"form-data", [{"name", "\"fifth_key\""}, {"filename", "\"file.txt\""}]}, []}
]
})
```
### URL Encoded Requests
```elixir
# This structure will be used in the following examples
other_structure = %{
one: "two",
three: "four"
}
```
#### Example 2
```elixir
with {:ok, payload} <- FormData.create(other_structure, :url_encoded),
do: HTTPoison.post("some.url/", payload)
# The above code produces the following request
HTTPoison.post("some.url/", {
:form,
[
{"one", "two"},
{"three", "four"}
]
})
```
#### Example 3
```elixir
with {:ok, payload} <- FormData.create(other_structure, :url_encoded, get: true),
do: HTTPoison.get("some.url/", %{}, payload)
# The above code produces the following request
HTTPoison.get("some.url/", %{}, params: [
{"one", "two"},
{"three", "four"}
])
```
## Notes
Although the examples do not show this, `url_encoded` formdata supports nested
structures the same as `multipart`, but will ignore any `%FormData.File{}`
structs, since `url_encoded` requests do not support file uploads.
## Contributors
- [Riley Trautman](https://github.com/asonix), asonix.dev@gmail.com
## Lincense
```
Copyright © 2016 Spiceworks, Inc.
This work is free. You can redistribute it and/or modify it under the
terms of the MIT License. See the LICENSE file for more details.
```