lud
Basic code to use mint (http client)
Hello,
I am trying to use mint to make some http requests with Elixir, and reading the docs I wrote the following code.
It works fine (for basic GET requests and everything is hardcoded, it’s normal, just a test) but it seems a bit to much to use a library.
Questions at the end of the post.
defmodule HTTP do
@empty_state %{data: [], done: false}
def run do
with {:ok, conn} <- Mint.HTTP.connect(:http, "httpbin.org", 80),
{:ok, conn, _ref} <- Mint.HTTP.request(conn, "GET", "/", [], nil) do
handle_response(conn, @empty_state)
end
end
defp handle_response(conn, state) do
receive do
message ->
case Mint.HTTP.stream(conn, message) do
{:ok, conn, responses} ->
case Enum.reduce(responses, state, &handle_res/2) do
# Loop ends here
%{done: true} = state -> {:ok, state}
%{done: false} = state -> handle_response(conn, state)
end
{:error, _, reason, _} ->
{:error, reason}
:unknown ->
exit({:unexpected, message})
end
end
end
defp handle_res({:status, _, status}, state),
do: Map.put(state, :status, status)
defp handle_res({:headers, _, headers}, state),
do: Map.put(state, :headers, headers)
defp handle_res({:data, _, data}, state),
do: Map.update!(state, :data, fn acc -> [data | acc] end)
defp handle_res({:done, _}, state) do
Map.update!(state, :data, fn acc ->
acc
|> :lists.reverse()
|> Enum.join("")
end)
|> Map.put(:done, true)
end
end
Task.async(fn -> HTTP.run() end)
|> Task.await()
|> case do
{:ok, state} ->
state
|> Map.get(:data)
|> IO.puts()
other ->
IO.inspect(other, pretty: true)
end
A quick note : I intend to use this from a GenServer, and I have no concerns about performance for this project, so to avoid handling messages, I will spawn a Task to handle the request, so I do not care about the request reference or :unknown messages. Also I know there are other responses possibles.
But again I do not expect other messages.
Questions
- Is my code
:ok? I’ll take any remarks. - Am I expected to do that to use this library ?
- Do you think
mintshould provide a helper like this for basic single requests ? - If I got it right,
connect/3is separated fromrequest/5for connection reuse. Can I do multiple requests with the sameconn? And if yes, should I use the conn fromconnect()or the last updated one ?
Thank you !
Most Liked
dimitarvp
I highly recommend Tesla. It supports changing of the underlying HTTP client while providing a very sensible and convenient thin abstraction layer above them.
jola
If you’re just looking to make some requests, look at HTTPoison (based on hackney) or Mojito (based on Mint).
Mint is a low level library which is pretty high effort if you’re not looking specifically for the features it offers. It explicitly doesn’t provide helpers to do requests, look at Mojito for that.
outlog
what @jola said - just wanted to add the tesla https://github.com/teamon/tesla library which is pretty nice for creating an abstraction/module for your different requests etc…







