Usage
View SourceMix.install([
{:curl_req, github: "derekkraan/curl_req", override: true},
{:merquery, "~> 0.3.0"},
{:kino, "~> 0.14.2"},
])
From cURL to Req
To generate a Req
struct from a cURL command, you can either use the function CurlReq.from_curl/1
or the sigil_CURL
.
import CurlReq
sigil = ~CURL(https://httpbin.org/get)
function = CurlReq.from_curl("curl https://httpbin.org/get")
Both produce the same Req.Request
but the macro checks the validity at compile time and you don't have to escape the string. As you can see, the cURL command itself ("curl") gets ignored and produces the same request.
sigil === function
Let's see if CurlReq
can understand a more complex cURL command
~CURL(curl -H "Accept-Encoding: gzip" -H "User-Agent: firefox/111" https://httpsbin.org/get)
As we can see, the User-Agent ist stored in the header map but where is the Accept-Encoding header? If you look closely at the Req.Request
struct, you can see that a new request step was added (&Req.Steps.compressed/1
). CurlReq
tries to use/translate the native functionalities of the underlying HTTP client, in this case Req
.
From Req to cURL
req = Req.new(base_url: "http://httpbin.org", url: "/post", method: :post, json: %{foo: "bar"})
curl = CurlReq.to_curl(req)
To read it better we can hide the double string escaping with some Kino
helpers
Kino.Shorts.text(curl)
As you can see, the correct Accept headers get set and the JSON body gets correctly escaped.
Flag style
You can control if you want short or long flags in the generated cURL command
CurlReq.to_curl(req, flags: :long)
Flavor
You can control if you wan't to use the Req user agent instead of the native cURL command and if you want to set the implicit headers explicitly with this opion
CurlReq.to_curl(req, flavor: :req)
Third party integration
CurlReq
is used in Merquery
which describes itself as "Powered by the wonderful Req
library, Merquery is an interactive and extensible
HTTP client for Elixir and Livebook"
If you select the Plugins
tab in the Smart Cell below you can activate the CurlReq
plugin. This will log the request you make as a cURL command as you make the request. Just enter an URL and evaluate the cell, it will print the cURL command and after that the Req.Response
.
req = Req.new(method: :get, url: "", headers: %{}, params: %{})
{req, resp} = Req.request(req)
resp
Another cool feature of merquery
is, that you can import your cURL commands directly. Just copy the following request
curl --compressed -H "foo: bar" -X GET http://httpbin.org/get
and select the import icon from the top right of the Merquery cell below and paste it in the text area which will open.
req = Req.new(method: :get, url: "", headers: %{}, params: %{})
{req, resp2} = Req.request(req)
resp2
>>>>>>> Stashed changes
Advanced Usage
Internally everything gets converted to a CurlReq.Request
struct. So you can modify it and generate the cURL and Req commands from that. Say we wouldn't know how to set the user agent with the cURL command. The solution would be to add it afterwards with CurlReq.Request.put_user_agent/2
and then encode it as a Req
struct.
request = CurlReq.Curl.decode("curl -k -X POST https://example.com")
request = CurlReq.Request.put_user_agent(request, "my_user_agent/1.0")
CurlReq.Req.encode(request)
You could also implement the CurlReq.Request
behaviour for other HTTP clients. Here's an example for a non existing fake client.
defmodule MyHTTPClient do
defstruct [:url, method: :get]
@behaviour CurlReq.Request
import CurlReq.Request
@impl CurlReq.Request
def decode(%__MODULE__{} = request, _opts \\ []) do
%CurlReq.Request{}
|> put_method(request.method)
|> put_url(request.url)
end
@impl CurlReq.Request
def encode(%CurlReq.Request{} = request, _opts \\ []) do
%__MODULE__{url: URI.to_string(request.url), method: request.method}
end
end
%MyHTTPClient{url: "https://example.com", method: :post}
|> MyHTTPClient.decode()
|> CurlReq.Curl.encode()
"curl -X PUT https://example.com"
|> CurlReq.Curl.decode()
|> MyHTTPClient.encode()