BitGonzo

BitGonzo

Sensible way to abstract away request client library in my application?

I’ve started to test my application and immediately run into the mock debate. Just done reading:

The above suggests using explicit contracts and config variables to manage environment-specific dependencies initially, and then goes on to suggest the simpler method of injecting dependency directly.

However, my current method is a little different. I am using explicit contracts and delegation such as:

config :myapp, request_client: MyApp.Tesla.Request

defmodule MyApp.Request do
  @client Application.get_env(:myapp, :request_client)

  defdelegate make, to: @client

  @callback make(etc) :: etc
end

defmodule MyApp.Tesla.Request do
  @behaviour MyApp.Request

  use Tesla
  plug Tesla.Middleware.Retry, delay: 1000, max_retries:: 3

  def make do
    # perform request, return response
  end
end

This gives me a common interface and call MyApp.Request.make, while also giving me the ability to switch out the client with configuration, which I will use during testing.

Does this look sensible? Is there something inherently wrong with the above approach or, in your opinion, an improvement?

The second question is about testing MyApp.Tesla.Request – perhaps I can switch out the client I use in testing, but surely I still need to test that my Tesla request is configured/running properly.

Most Liked

BitGonzo

BitGonzo

Awesome! I’m on Vim. I imagine there is a plugin, or could write a simple one. At the minute I’m just running dialyzer as part of my build process.

Yup - https://github.com/fishcakez/vim-dialyzer

hubertlepicki

hubertlepicki

Maybe examples here will make it a bit more clear: http://slides.com/hubertlepicki/mox

NobbZ

NobbZ

So dialyzer is totally right.

Tesla.get/* and Tesla.post/* all are returning Tesla.Env.t according to their @spec. A Tesla.Env.t will never match a {:ok, _} as it is a struct, not a tuple.

If though Tesla.get/* does return a tuple instead, you need to file a bugreport at tesla to fix their specs (or implementation).

BitGonzo

BitGonzo

I don’t understand. That code works – the result of Tesla.get is a tuple with {:ok, response} or {:error, struct (with reason)}?

In that case - if this is a bug in their spec/impl, apart from telling Tesla about it, what would be the proper way to handle this? Patch the spec myself? Wait for it to be fixed? Tell dialyzer to ignore?

NobbZ

NobbZ

Its easiy.

You are using Tesla.get/1, which is @speced to return Tesla.Env.t, but implemented to return {:ok, any()} | {:error, any()} (or something similar).

You are running dialyzer in the context of your application, so dialyzer will trust in the specs of external libraries without validating them.

If you were running dialyzer in the context of Tesla it will probably complain that the functions do not fullfill their contract (do not remember the exact message).

Where Next?

Popular in Questions Top

freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
dokuzbir
Hello, I am trying to convert my lists to string without losing brackets.For start i have 3 map. They look like these buyer = %{ id: ...
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
vac
Hi, I'm quite new in Elixir and I'm trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and ...
New
johnnyicon
Hi all, I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I'm trying to use Postg...
New
hpopp
To simplify some tasks at work, I wrote and published this package yesterday. It’s a simple macro that enables Access behaviour on struct...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
idi527
I’ve been re-reading swift book again and noticed that multiline strings there don’t have a trailing line break, unlike in elixir iex(2)...
New

Other popular topics Top

srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call th...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New
yawaramin
In the Dialyzer docs ( http://erlang.org/doc/man/dialyzer.html#requesting-or-suppressing-warnings-in-source-files ), there is a way to tu...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
Jim
As a follow up to my earlier question: I have the code compiling and running but not getting a successful login from the rest server. ...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 42633 214
New
johnnyicon
Hi all, I've just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I'm trying to use Postg...
New
beno
I will often find my self writing things similar to: case some_value do nil -> something() "" -> something() _ -> someth...
New
AstonJ
by Lance Halvorsen Elixir and Phoenix are generating tremendous excitement as an unbeatable platform for building modern web application...
460 27162 124
New

We're in Beta

About us Mission Statement