Skip to content

Cookbook: URL templates

Tymon Tobolski edited this page Jul 22, 2020 · 3 revisions

UPDATE: You can now use the built-in PathParams middleware

(old version below)


by @nicolasgarnil

Sometimes you may want to keep the URL as template with parameters placeholders to report it (think metrics) and later replace it with real params.

defmodule MyAPI.Middleware.UrlBuilder do
  @moduledoc """
  Builds the request url
  """

  @behaviour Tesla.Middleware

  @impl Tesla.Middleware
  def call(env, next, _) do
    url = build_url(env.url, env.opts[:params])
    opts = Keyword.merge(env.opts, url: env.url)

    Tesla.run(%{env | url: url, opts: opts}, next)
  end

  defp build_url(url, nil), do: url

  defp build_url(url, params) do
    Enum.reduce(params, url, fn {k, v}, u ->
      String.replace(u, ":#{k}", to_string(v))
    end)
  end
end
defmodule MyAPI do
  use Tesla

  plug Tesla.Middleware.BaseUrl, "http://example.com"

  plug MyAPI.Middleware.UrlBuilder

  def get_user(user_id) do
    get("/user/:id", opts: [params: [id: user_id]])
  end
end