Help with passing param list in hackney GET body

Hey all,

I’m trying to make a GET request while passing in body params. One param requires a list of strings. The API documentation states:

curl -s --user 'api:YOUR_API_KEY' -G \
   https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/stats/total \
   -d event='accepted' \
   -d event='delivered' \
   -d event='failed' \
   -d duration='1m'

In Elixir, here is how I’m preparing the body:

    body =
      %{event: ["accepted"]}
      |> Plug.Conn.Query.encode

However the response I get is:

    ** (Bamboo.ApiError) There was a problem sending the email through the Mailgun API.

Here is the response:

"{\"message\":\"please provide at least one event: Missing mandatory parameter: event\"}\n"

Here are the params we sent:

"event[]=accepted"

Any ideas on what i’m doing wrong here?

First, that curl is not using body. See -G option - it uses data under -d as query parameter.

If you use -v option in curl - you can see the data are in the query string - ?event=accepted&event=delivered&event=failed&duration=1m

Okay - so you just need to build the query parameter then. You can use URI.encode_query/1.

URI.encode_query([event: "accepted", event: "delivered", event: "failed", duration: "1m"])
# => "event=accepted&event=delivered&event=failed&duration=1m"

Note

  • keywords allows duplicate keys
  • URI.encode_query/1 accepts atom

I really like the design of Elixir standard lib here - query parameter should not be implemented as map (as duplicate key is possible) and the order is preserved (as in keywords), and no magic transformation (e.g. passing list as value) . I saw many “easy to use” http interface are based on wrong assumption on many details…

What kind of list? Comma-separated? Or a JSON-style list?

If the latter, your parameter can be encoded like so:

...?event[]=1&event[]=2&event[]=3

A lot of framework backends – Plug (and thus Phoenix) included – will decode the above as event=[1,2,3].

Can you include the code that calls out to Mailgun? I see the query preparation, but not how that is actually being sent along. My initial guess is that maybe that part is not setup correctly.

Do you mean query params? GET requests technically can have a body, but I would put the chances of a service respecting it very low.

1 Like