Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce Tesla.Client with pre/post middleware #104

Merged
merged 3 commits into from
Sep 21, 2017
Merged

Conversation

teamon
Copy link
Member

@teamon teamon commented Sep 11, 2017

This change is backward compatible:

  • Tesla.build_client API stays the same
  • one can still use simple function as a client

Tesla.Client struct can hold any custom fun (as before)
but can now hold pre and post middleware lists.
pre works the same way as one given to build_client.
post middleware is injected right before adapter.
It can be used as a regular middleware but can be also
used to dynamically override adapter in runtime.
This is mostly useful in testing:

defmodule MyAPI do
  use Tesla

  def help(client \\ %Tesla.Client{}) do
    get(client, "/help")
  end
end

client = Tesla.build_adapter fn env ->
  %{env | status: 200, body: "new body"}
end

assert %{body: "new body"} = MyAPI.get(client)

@amatalai
Copy link
Collaborator

I believe these two should be referenced here #94 #97 :)

This was referenced Sep 11, 2017
This change is backward compatible:
- Tesla.build_client API stays the same
- one can still use simple function as a client

Tesla.Client struct can hold any custom `fun` (as before)
but can now hold `pre` and `post` middleware lists.
`pre` works the same way as one given to `build_client`.
`post` middleware is injected right before adapter.
It can be used as a regular middleware but can be also
used to dynamically override adapter in runtime.
This is mostly useful in testing
@teamon
Copy link
Member Author

teamon commented Sep 14, 2017

As far as #94 is concerned there is one more way to do this (and I'm surprised I haven't thought about it earlier)

defmodule Cached do
  use Tesla

  adapter :cache

  def cache(env) do
    cond do
      String.ends_with?(env.url, "/cached") ->
        %{env | body: "cached", status: 304}
      true ->
        Tesla.run_default_adapter(env)
    end
  end
end

All one needs to do is to write a custom adapter that wraps other adapter.
I've added Tesla.run_default_adapter/1,2 as part of this PR to make it more convenient to use the default adapter which can be configured globally.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants