We had some code that would build a URI using three parts: a scheme, a host and a port. The port should not be included if it’s 80 because we might want to build http://example.com:8080
but never http://example.com:80
(http://example.com
is much nicer even though it’s the same thing).
case port do
80 -> "#{scheme}://#{host}"
port -> "#{scheme}://#{host}:#{port}"
end
I’m not a fan of string interpolation with arbitrary values and literals (eg. ://
) so I knew there’s had to be a better way to build URIs with Elixir. URI.to_string/1
is the way.
%URI{host: "example.com", scheme: "http"} |> URI.to_string()
"http://example.com"
%URI{host: "example.com", scheme: "http", port: 80} |> URI.to_string()
"http://example.com"
%URI{host: "example.com", scheme: "http", port: 81} |> URI.to_string()
"http://example.com:81"
%URI{host: "example.com", scheme: "http", port: 443} |> URI.to_string()
"http://example.com:443"
%URI{host: "example.com", scheme: "https", port: 443} |> URI.to_string()
"https://example.com"
And turns out, URI.to_string/1
uses URI.default_port/1
to figure out if the port has to be explicitely included in the string representation 🎉 so we don’t need to worry about it anymore!
And just for fun, here are the default ports known by Elixir 1.13:
URIConfig = [
{{uri, <<"ftp">>}, 21},
{{uri, <<"sftp">>}, 22},
{{uri, <<"tftp">>}, 69},
{{uri, <<"http">>}, 80},
{{uri, <<"https">>}, 443},
{{uri, <<"ldap">>}, 389}
]