I have a simple module responsible for communicating with an API. As a convenience to the user, I allow users to pass a "short" url /my/route
or the full url https://api.mysite.com
and handle it with HTTPoison
's process_url
method:
defmodule MyApp.MyApiHandler do
use HTTPoison.base
@endpoint = "https://api.mysite.com"
def process_url(@endpoint <> _path = url), do: url
def process_url(url), do: @endpoint <> url
end
This works perfectly! Urls that start with the endpoint are unmodified, and those don't have endpoint added.
The issue I'm encountering is when I try to move this endpoint from a module attribute to a method that reads from config at run time:
defmodule MyApp.MyApiHandler do
use HTTPoison.base
def process_url(endpoint() <> _path = url), do: url
def process_url(url), do: endpoint() <> url
defp endpoint do
Application.get_env(:MyApp, __MODULE__)[:endpoint]
end
end
I receive the following error
lib/my_api_handler.ex: cannot invoke local endpoint/0 inside match, called as endpoint()
I'd really prefer to store this config in config (so I can change it per environment). Is there a way to do that while preserving the matching?
The existing SO question for this error doesn't seem to cover my use case (I'm not attempting to assign in the match) but I could also be wrong there.
You can define endpoint
as a macro.
E.g,
defmodule Test do
defmacro endpoint do
Application.get_env(:MyApp, __MODULE__)[:endpoint]
end
def process_url(endpoint() <> _path = url), do: url
def process_url(url), do: endpoint() <> url
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With