-
Notifications
You must be signed in to change notification settings - Fork 342
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
Customizable Client struct module #123
Comments
Hi! Can you show an example of your code? I don't think we can skip the |
To clarify, the point of this wouldn't be to skip the Currently, this works fine, because defmodule APIOne do
use Tesla
def client do
Tesla.build_client [
{Tesla.Middleware.Headers, %{"Authorization" => "token: " <> token }}
]
end
end
defmodule APITwo, do: use Tesla
APITwo.get(APIOne.client, "foo") My proposal is to allow Tesla to generate client structs 'private' to a particular invocation of defmodule APIOne do
use Tesla, client: APIOne.Client
def client do
APIOne.Client.build [
{Tesla.Middleware.Headers, %{"Authorization" => "token: " <> token }}
]
end
end
defmodule APITwo, do: use Tesla, client: APITwo.Client
APITwo.get(APIOne.client, "foo") raises:
Because, since |
Here, this is kind of what I was envisioning. |
Closing in favour of #133 |
Hello again! You may remember me from such issues as #122. 😄
The project I'm working on wraps several APIs. This means that I'm
__using__
Tesla in a few places to construct several API client modules with different behaviours.Each API client is associated with several modules that actually perform the API calls––the surface of these APIs is very wide and benefits from being split up into conceptual buckets.
It would be nice to have my API-client-calling modules type-check that you are using the correct client for the given module. The cleanest and most idiomatic way to do this would be to pattern match on the client struct type, but all Tesla-built clients are
Tesla.Client
structs. It would be helpful if I could customize the struct for any given call touse Tesla
.I envision providing an extra option to the using call, i.e:
use Tesla, client: My.API.Client
. If this parameter is provided it would define a new struct and thread it throughout all pattern matching on its type in Tesla macros. If it is not provided it would thread the existingTesla.Client
module reference through instead, keeping everything backwards compatible.This seems possible based on the current implementation of Tesla––all pattern matching on the module name of the client struct lives within macro calls that could be meta-programmed or parameterized. The few other places it is explicitly referenced we could adjust for, I have some ideas on how to manage. With your blessing I would be happy to pursue this further and submit a PR.
The places we are currently matching on it are within the builder:
Tesla.Builder
defmacro __using__
def request(%Tesla.Client{} = client, options)
defp generate_api(method, docs) when method in [:post, :put, :patch]
def unquote(method)(%Tesla.Client{} = client, url, body, options) when is_list(options)
def unquote(method)(fun, url, body, options) when is_function(fun) and is_list(options)
unquote(method)(%Tesla.Client{fun: fun}, url, body, options)
def unquote(method)(%Tesla.Client{} = client, url, body)
def unquote(method)(fun, url, body) when is_function(fun)
unquote(method)(%Tesla.Client{fun: fun}, url, body)
defp generate_api(method, docs) when method in [:head, :get, :delete, :trace, :options]
def unquote(method)(%Tesla.Client{} = client, url, body, options) when is_list(options)
def unquote(method)(fun, url, body, options) when is_function(fun) and is_list(options)
unquote(method)(%Tesla.Client{fun: fun}, url, body, options)
def unquote(method)(%Tesla.Client{} = client, url)
def unquote(method)(fun, url) when is_function(fun)
unquote(method)(%Tesla.Client{fun: fun}, url)
The text was updated successfully, but these errors were encountered: