diff --git a/lib/tesla/middleware/base_url.ex b/lib/tesla/middleware/base_url.ex index 2802ff3d..ff6bf7e9 100644 --- a/lib/tesla/middleware/base_url.ex +++ b/lib/tesla/middleware/base_url.ex @@ -7,17 +7,26 @@ defmodule Tesla.Middleware.BaseUrl do ## Examples - ``` + ```elixir defmodule MyClient do - use Tesla - - plug Tesla.Middleware.BaseUrl, "https://example.com/foo" + def client do + Tesla.client([Tesla.Middleware.BaseUrl, "https://example.com/foo"]) + end end - MyClient.get("/path") # equals to GET https://example.com/foo/path - MyClient.get("path") # equals to GET https://example.com/foo/path - MyClient.get("") # equals to GET https://example.com/foo - MyClient.get("http://example.com/bar") # equals to GET http://example.com/bar + client = MyClient.client() + + Tesla.get(client, "/path") + # equals to GET https://example.com/foo/path + + Tesla.get(client, "path") + # equals to GET https://example.com/foo/path + + Tesla.get(client, "") + # equals to GET https://example.com/foo + + Tesla.get(client, "http://example.com/bar") + # equals to GET http://example.com/bar ``` """ diff --git a/lib/tesla/middleware/basic_auth.ex b/lib/tesla/middleware/basic_auth.ex index 478e412a..ab9be5c2 100644 --- a/lib/tesla/middleware/basic_auth.ex +++ b/lib/tesla/middleware/basic_auth.ex @@ -6,15 +6,9 @@ defmodule Tesla.Middleware.BasicAuth do ## Examples - ``` + ```elixir defmodule MyClient do - use Tesla - - # static configuration - plug Tesla.Middleware.BasicAuth, username: "user", password: "pass" - - # dynamic user & pass - def new(username, password, opts \\\\ %{}) do + def client(username, password, opts \\ %{}) do Tesla.client [ {Tesla.Middleware.BasicAuth, Map.merge(%{username: username, password: password}, opts)} ] diff --git a/lib/tesla/middleware/bearer_auth.ex b/lib/tesla/middleware/bearer_auth.ex index a1df0787..f5e5993a 100644 --- a/lib/tesla/middleware/bearer_auth.ex +++ b/lib/tesla/middleware/bearer_auth.ex @@ -8,12 +8,6 @@ defmodule Tesla.Middleware.BearerAuth do ``` defmodule MyClient do - use Tesla - - # static configuration - plug Tesla.Middleware.BearerAuth, token: "token" - - # dynamic token def new(token) do Tesla.client [ {Tesla.Middleware.BearerAuth, token: token} diff --git a/lib/tesla/middleware/compression.ex b/lib/tesla/middleware/compression.ex index 5ba1fcd0..0f026850 100644 --- a/lib/tesla/middleware/compression.ex +++ b/lib/tesla/middleware/compression.ex @@ -6,11 +6,11 @@ defmodule Tesla.Middleware.Compression do ## Examples - ``` + ```elixir defmodule MyClient do - use Tesla - - plug Tesla.Middleware.Compression, format: "gzip" + def client do + Tesla.client([Tesla.Middleware.Compression, format: "gzip"]) + end end ``` diff --git a/lib/tesla/middleware/decode_rels.ex b/lib/tesla/middleware/decode_rels.ex index a5404134..8add388b 100644 --- a/lib/tesla/middleware/decode_rels.ex +++ b/lib/tesla/middleware/decode_rels.ex @@ -4,14 +4,16 @@ defmodule Tesla.Middleware.DecodeRels do ## Examples - ``` + ```elixir defmodule MyClient do - use Tesla - - plug Tesla.Middleware.DecodeRels + def client do + Tesla.client([Tesla.Middleware.DecodeRels]) + end end - env = MyClient.get("/...") + client = MyClient.client() + + env = Tesla.get(client, "/...") env.opts[:rels] # => %{"Next" => "http://...", "Prev" => "..."} diff --git a/lib/tesla/middleware/digest_auth.ex b/lib/tesla/middleware/digest_auth.ex index b26a8875..db278649 100644 --- a/lib/tesla/middleware/digest_auth.ex +++ b/lib/tesla/middleware/digest_auth.ex @@ -11,8 +11,6 @@ defmodule Tesla.Middleware.DigestAuth do ``` defmodule MyClient do - use Tesla - def client(username, password, opts \\ %{}) do Tesla.client([ {Tesla.Middleware.DigestAuth, Map.merge(%{username: username, password: password}, opts)} @@ -22,6 +20,7 @@ defmodule Tesla.Middleware.DigestAuth do ``` ## Options + - `:username` - username (defaults to `""`) - `:password` - password (defaults to `""`) - `:cnonce_fn` - custom function generating client nonce (defaults to `&Tesla.Middleware.DigestAuth.cnonce/0`) diff --git a/lib/tesla/middleware/follow_redirects.ex b/lib/tesla/middleware/follow_redirects.ex index 25c44b99..2575c4b6 100644 --- a/lib/tesla/middleware/follow_redirects.ex +++ b/lib/tesla/middleware/follow_redirects.ex @@ -4,11 +4,12 @@ defmodule Tesla.Middleware.FollowRedirects do ## Examples - ``` + ```elixir defmodule MyClient do - use Tesla - - plug Tesla.Middleware.FollowRedirects, max_redirects: 3 # defaults to 5 + def client do + # defaults to 5 + Tesla.client([Tesla.Middleware.FollowRedirects, max_redirects: 3]) + end end ``` diff --git a/lib/tesla/middleware/form_urlencoded.ex b/lib/tesla/middleware/form_urlencoded.ex index c69762fa..df1e431c 100644 --- a/lib/tesla/middleware/form_urlencoded.ex +++ b/lib/tesla/middleware/form_urlencoded.ex @@ -11,11 +11,11 @@ defmodule Tesla.Middleware.FormUrlencoded do ## Examples - ``` + ```elixir defmodule Myclient do - use Tesla - - plug Tesla.Middleware.FormUrlencoded + def client do + Tesla.client([Tesla.Middleware.FormUrlencoded]) + end end Myclient.post("/url", %{key: :value}) @@ -33,13 +33,15 @@ defmodule Tesla.Middleware.FormUrlencoded do Support for this specific case is obtained by configuring the middleware to encode (and decode) with `Plug.Conn.Query` - ``` + ```elixir defmodule Myclient do - use Tesla - - plug Tesla.Middleware.FormUrlencoded, - encode: &Plug.Conn.Query.encode/1, - decode: &Plug.Conn.Query.decode/1 + def client do + Tesla.client([ + Tesla.Middleware.FormUrlencoded, + encode: &Plug.Conn.Query.encode/1, + decode: &Plug.Conn.Query.decode/1 + ]) + end end Myclient.post("/url", %{key: %{nested: "value"}}) diff --git a/lib/tesla/middleware/fuse.ex b/lib/tesla/middleware/fuse.ex index 9c20c602..891bd5e3 100644 --- a/lib/tesla/middleware/fuse.ex +++ b/lib/tesla/middleware/fuse.ex @@ -13,19 +13,21 @@ if Code.ensure_loaded?(:fuse) do ## Examples - ``` + ```elixir defmodule MyClient do - use Tesla - - plug Tesla.Middleware.Fuse, - opts: {{:standard, 2, 10_000}, {:reset, 60_000}}, - keep_original_error: true, - should_melt: fn - {:ok, %{status: status}} when status in [428, 500, 504] -> true - {:ok, _} -> false - {:error, _} -> true - end, - mode: :sync + def client do + Tesla.client([ + Tesla.Middleware.Fuse, + opts: {{:standard, 2, 10_000}, {:reset, 60_000}}, + keep_original_error: true, + should_melt: fn + {:ok, %{status: status}} when status in [428, 500, 504] -> true + {:ok, _} -> false + {:error, _} -> true + end, + mode: :sync + ]) + end end ``` @@ -46,7 +48,7 @@ if Code.ensure_loaded?(:fuse) do You can disable its logger output using: - ``` + ```elixir config :sasl, sasl_error_logger: :false ``` diff --git a/lib/tesla/middleware/headers.ex b/lib/tesla/middleware/headers.ex index 0e0ac3d0..12f6d584 100644 --- a/lib/tesla/middleware/headers.ex +++ b/lib/tesla/middleware/headers.ex @@ -4,11 +4,11 @@ defmodule Tesla.Middleware.Headers do ## Examples - ``` + ```elixir defmodule Myclient do - use Tesla - - plug Tesla.Middleware.Headers, [{"user-agent", "Tesla"}] + def client do + Tesla.client([Tesla.Middleware.Headers, [{"user-agent", "Tesla"}]]) + end end ``` """ diff --git a/lib/tesla/middleware/json.ex b/lib/tesla/middleware/json.ex index ac183cbe..cb76c369 100644 --- a/lib/tesla/middleware/json.ex +++ b/lib/tesla/middleware/json.ex @@ -19,15 +19,18 @@ defmodule Tesla.Middleware.JSON do ``` defmodule MyClient do - use Tesla - - plug Tesla.Middleware.JSON # use jason engine - # or - plug Tesla.Middleware.JSON, engine: JSX, engine_opts: [strict: [:comments]] - # or - plug Tesla.Middleware.JSON, engine: Poison, engine_opts: [keys: :atoms] - # or - plug Tesla.Middleware.JSON, decode: &JSX.decode/1, encode: &JSX.encode/1 + def client do + Tesla.client([ + # use jason engine + Tesla.Middleware.JSON, + # or + Tesla.Middleware.JSON, engine: JSX, engine_opts: [strict: [:comments]], + # or + Tesla.Middleware.JSON, engine: Poison, engine_opts: [keys: :atoms], + # or + Tesla.Middleware.JSON, decode: &JSX.decode/1, encode: &JSX.encode/1 + ]) + end end ``` diff --git a/lib/tesla/middleware/keep_request.ex b/lib/tesla/middleware/keep_request.ex index a2803619..30cd3446 100644 --- a/lib/tesla/middleware/keep_request.ex +++ b/lib/tesla/middleware/keep_request.ex @@ -6,13 +6,16 @@ defmodule Tesla.Middleware.KeepRequest do ``` defmodule MyClient do - use Tesla - - plug Tesla.Middleware.KeepRequest - plug Tesla.Middleware.PathParams + def client do + Tesla.client([ + Tesla.Middleware.KeepRequest, + Tesla.Middleware.PathParams + ]) + end end - {:ok, env} = MyClient.post("/users/:user_id", "request-data", opts: [path_params: [user_id: "1234"]]) + client = MyClient.client() + {:ok, env} = Tesla.post(client, "/users/:user_id", "request-data", opts: [path_params: [user_id: "1234"]]) env.body # => "response-data" diff --git a/lib/tesla/middleware/logger.ex b/lib/tesla/middleware/logger.ex index 0db42ae6..d8dc737f 100644 --- a/lib/tesla/middleware/logger.ex +++ b/lib/tesla/middleware/logger.ex @@ -62,9 +62,9 @@ defmodule Tesla.Middleware.Logger do ```elixir defmodule MyClient do - use Tesla - - plug Tesla.Middleware.Logger + def client do + Tesla.client([Tesla.Middleware.Logger]) + end end ``` @@ -80,7 +80,7 @@ defmodule Tesla.Middleware.Logger do The default log format is `"$method $url -> $status ($time ms)"` which shows in logs like: - ``` + ```elixir 2018-03-25 18:32:40.397 [info] GET https://bitebot.io -> 200 (88.074 ms) ``` @@ -116,9 +116,9 @@ defmodule Tesla.Middleware.Logger do ```elixir defmodule MyClient do - use Tesla - - plug Tesla.Middleware.Logger, log_level: &my_log_level/1 + def client do + Tesla.client([Tesla.Middleware.Logger, log_level: &my_log_level/1]) + end def my_log_level(env) do case env.status do @@ -138,7 +138,7 @@ defmodule Tesla.Middleware.Logger do but keep the `:debug` log level (i.e. in development) you can set `debug: false` in your config: - ``` + ```elixir # config/dev.local.exs config :tesla, Tesla.Middleware.Logger, debug: false ``` @@ -146,7 +146,7 @@ defmodule Tesla.Middleware.Logger do Note that the logging configuration is evaluated at compile time, so Tesla must be recompiled for the configuration to take effect: - ``` + ```shell mix deps.clean --build tesla mix deps.compile tesla ``` @@ -171,7 +171,7 @@ defmodule Tesla.Middleware.Logger do debug logs, add them to the `:filter_headers` option. `:filter_headers` expects a list of header names as strings. - ``` + ```elixir # config/dev.local.exs config :tesla, Tesla.Middleware.Logger, filter_headers: ["authorization"] diff --git a/lib/tesla/middleware/message_pack.ex b/lib/tesla/middleware/message_pack.ex index ce37d358..3e2fa8c1 100644 --- a/lib/tesla/middleware/message_pack.ex +++ b/lib/tesla/middleware/message_pack.ex @@ -8,7 +8,7 @@ if Code.ensure_loaded?(Msgpax) do Remember to add `{:msgpax, ">= 2.3.0"}` to dependencies. Also, you need to recompile Tesla after adding `:msgpax` dependency: - ``` + ```shell mix deps.clean tesla mix deps.compile tesla ``` @@ -19,11 +19,15 @@ if Code.ensure_loaded?(Msgpax) do defmodule MyClient do use Tesla - plug Tesla.Middleware.MessagePack - # or - plug Tesla.Middleware.MessagePack, engine_opts: [binary: true] - # or - plug Tesla.Middleware.MessagePack, decode: &Custom.decode/1, encode: &Custom.encode/1 + def client do + Tesla.client([ + Tesla.Middleware.MessagePack, + # or + Tesla.Middleware.MessagePack, engine_opts: [binary: true], + # or + Tesla.Middleware.MessagePack, decode: &Custom.decode/1, encode: &Custom.encode/1 + ]) + end end ``` diff --git a/lib/tesla/middleware/method_override.ex b/lib/tesla/middleware/method_override.ex index 7cad2aa2..cd4d023a 100644 --- a/lib/tesla/middleware/method_override.ex +++ b/lib/tesla/middleware/method_override.ex @@ -7,11 +7,11 @@ defmodule Tesla.Middleware.MethodOverride do ## Examples - ``` + ```elixir defmodule MyClient do - use Tesla - - plug Tesla.Middleware.MethodOverride + def client do + Tesla.client([Tesla.Middleware.MethodOverride]) + end end ``` diff --git a/lib/tesla/middleware/opts.ex b/lib/tesla/middleware/opts.ex index 6ca14b66..3b4d58a8 100644 --- a/lib/tesla/middleware/opts.ex +++ b/lib/tesla/middleware/opts.ex @@ -4,11 +4,11 @@ defmodule Tesla.Middleware.Opts do ## Examples - ``` - defmodule Myclient do - use Tesla - - plug Tesla.Middleware.Opts, [some: "option"] + ```elixir + defmodule MyClient do + def client do + Tesla.client([Tesla.Middleware.Opts, [some: "option"]]) + end end ``` """ diff --git a/lib/tesla/middleware/path_params.ex b/lib/tesla/middleware/path_params.ex index e9b98b9a..ff8bdac6 100644 --- a/lib/tesla/middleware/path_params.ex +++ b/lib/tesla/middleware/path_params.ex @@ -29,20 +29,22 @@ defmodule Tesla.Middleware.PathParams do ```elixir defmodule MyClient do - use Tesla - - plug Tesla.Middleware.BaseUrl, "https://api.example.com" - plug Tesla.Middleware.Logger # or some monitoring middleware - plug Tesla.Middleware.PathParams + def client do + Tesla.client([ + Tesla.Middleware.BaseUrl, "https://api.example.com", + Tesla.Middleware.Logger, + Tesla.Middleware.PathParams + ]) + end - def user(id) do + def user(client, id) do params = [id: id] - get("/users/{id}", opts: [path_params: params]) + Tesla.get(client, "/users/{id}", opts: [path_params: params]) end - def posts(id, post_id) do + def posts(client, id, post_id) do params = [id: id, post_id: post_id] - get("/users/:id/posts/:post_id", opts: [path_params: params]) + Tesla.get(client, "/users/:id/posts/:post_id", opts: [path_params: params]) end end ``` diff --git a/lib/tesla/middleware/query.ex b/lib/tesla/middleware/query.ex index b4dc3fc8..900d4c16 100644 --- a/lib/tesla/middleware/query.ex +++ b/lib/tesla/middleware/query.ex @@ -4,11 +4,11 @@ defmodule Tesla.Middleware.Query do ## Examples - ``` - defmodule Myclient do - use Tesla - - plug Tesla.Middleware.Query, [token: "some-token"] + ```elixir + defmodule MyClient do + def client do + Tesla.client([Tesla.Middleware.Query, [token: "some-token"]]) + end end ``` """ diff --git a/lib/tesla/middleware/retry.ex b/lib/tesla/middleware/retry.ex index 45754ef5..2a36bc58 100644 --- a/lib/tesla/middleware/retry.ex +++ b/lib/tesla/middleware/retry.ex @@ -21,27 +21,25 @@ defmodule Tesla.Middleware.Retry do ## Examples - ``` + ```elixir defmodule MyClient do - use Tesla - - plug Tesla.Middleware.Retry, - delay: 500, - max_retries: 10, - max_delay: 4_000, - should_retry: fn - {:ok, %{status: status}} when status in [400, 500] -> true - {:ok, _} -> false - {:error, _} -> true - end - # or - plug Tesla.Middleware.Retry, should_retry: fn - {:ok, %{status: status}}, _env, _context when status in [400, 500] -> true - {:ok, _reason}, _env, _context -> false - {:error, _reason}, %Tesla.Env{method: :post}, _context -> false - {:error, _reason}, %Tesla.Env{method: :put}, %{retries: 2} -> false - {:error, _reason}, _env, _context -> true - end + def client do + Tesla.client([ + {Tesla.Middleware.Retry, + delay: 500, + max_retries: 10, + max_delay: 4_000, + should_retry: fn + {:ok, %{status: status}}, _env, _context when status in [400, 500] -> true + {:ok, _reason}, _env, _context -> false + {:error, _reason}, %Tesla.Env{method: :post}, _context -> false + {:error, _reason}, %Tesla.Env{method: :put}, %{retries: 2} -> false + {:error, _reason}, _env, _context -> true + end + } + # or + ]) + end end ``` diff --git a/lib/tesla/middleware/sse.ex b/lib/tesla/middleware/sse.ex index ada9bfac..b9c396b2 100644 --- a/lib/tesla/middleware/sse.ex +++ b/lib/tesla/middleware/sse.ex @@ -6,9 +6,12 @@ defmodule Tesla.Middleware.SSE do ## Examples - ``` - plug Tesla.Middleware.SSE, only: :data - + ```elixir + defmodule MyClient do + def client do + Tesla.client([Tesla.Middleware.SSE, only: :data]) + end + end ``` ## Options diff --git a/lib/tesla/middleware/telemetry.ex b/lib/tesla/middleware/telemetry.ex index 633de1fc..39f4c8d3 100644 --- a/lib/tesla/middleware/telemetry.ex +++ b/lib/tesla/middleware/telemetry.ex @@ -5,11 +5,11 @@ if Code.ensure_loaded?(:telemetry) do ## Examples - ``` + ```elixir defmodule MyClient do - use Tesla - - plug Tesla.Middleware.Telemetry + def client do + Tesla.client([Tesla.Middleware.Telemetry]) + end end :telemetry.attach( @@ -56,14 +56,16 @@ if Code.ensure_loaded?(:telemetry) do ```elixir defmodule MyClient do - use Tesla - - # The KeepRequest middleware sets the template URL as a Tesla.Env.opts entry - # Said entry must be used because on happy-path scenarios, - # the Telemetry middleware will receive the Tesla.Env.url resolved by PathParams. - plug Tesla.Middleware.KeepRequest - plug Tesla.Middleware.PathParams - plug Tesla.Middleware.Telemetry + def client do + Tesla.client([ + # The KeepRequest middleware sets the template URL as a Tesla.Env.opts entry + # Said entry must be used because on happy-path scenarios, + # the Telemetry middleware will receive the Tesla.Env.url resolved by PathParams. + Tesla.Middleware.KeepRequest, + Tesla.Middleware.PathParams, + Tesla.Middleware.Telemetry + ]) + end end :telemetry.attach( diff --git a/lib/tesla/middleware/timeout.ex b/lib/tesla/middleware/timeout.ex index 90f4f3a4..5c1ebff8 100644 --- a/lib/tesla/middleware/timeout.ex +++ b/lib/tesla/middleware/timeout.ex @@ -4,23 +4,32 @@ defmodule Tesla.Middleware.Timeout do ## Examples - defmodule MyClient do - use Tesla - - plug Tesla.Middleware.Timeout, timeout: 2_000 - end + ```elixir + defmodule MyClient do + def client do + Tesla.client([ + Tesla.Middleware.Timeout, + timeout: 2_000 + ]) + end + end + ``` If you are using OpenTelemetry in your project, you may be interested in using `OpentelemetryProcessPropagator.Task` to have a better integration using the `task_module` option. - defmodule MyClient do - use Tesla - - plug Tesla.Middleware.Timeout, - timeout: 2_000, - task_module: OpentelemetryProcessPropagator.Task - end + ```elixir + defmodule MyClient do + def client do + Tesla.client([ + Tesla.Middleware.Timeout, + timeout: 2_000, + task_module: OpentelemetryProcessPropagator.Task + ]) + end + end + ``` ## Options diff --git a/test/tesla/middleware/timeout_test.exs b/test/tesla/middleware/timeout_test.exs index 3a51a76e..7408e307 100644 --- a/test/tesla/middleware/timeout_test.exs +++ b/test/tesla/middleware/timeout_test.exs @@ -131,7 +131,7 @@ defmodule Tesla.Middleware.TimeoutTest do [_, {timeout_module, _, _, module_file_info} | _] = __STACKTRACE__ assert Tesla.Middleware.Timeout == timeout_module - assert module_file_info == [file: ~c"lib/tesla/middleware/timeout.ex", line: 59] + assert module_file_info == [file: ~c"lib/tesla/middleware/timeout.ex", line: 68] else _ -> flunk("Expected exception to be thrown")