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

Custom client implementation. #133

Conversation

christhekeele
Copy link

Allows for creating Tesla-usage specific client structs, so multiple APIs within a project can own their own type of client.

Closes #123.

@codecov
Copy link

codecov bot commented Nov 1, 2017

Codecov Report

Merging #133 into master will increase coverage by 0.03%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #133      +/-   ##
==========================================
+ Coverage   98.28%   98.32%   +0.03%     
==========================================
  Files          21       21              
  Lines         409      417       +8     
==========================================
+ Hits          402      410       +8     
  Misses          7        7
Impacted Files Coverage Δ
lib/tesla.ex 100% <100%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f7fea9c...e35aebe. Read the comment docs.

@teamon
Copy link
Member

teamon commented Nov 28, 2017

While I understand your use case I'm not sure this is something that should be added to the core library. This looks like reimplementing type-safe generics in a language that wasn't made to support them.

I can think of one other option to achieve what you need, without changes to tesla itself.

defmodule TeslaCustomClientTest do
  use ExUnit.Case

  require Tesla
  @url "http://localhost:#{Application.get_env(:httparrot, :http_port)}"

  defmodule ApiA do
    defmodule Client do
      defstruct tesla: nil
    end

    defmodule Driver do
      use Tesla

      # add middlewares here
    end

    def new do
      %Client{tesla: Tesla.build_client([])}
    end

    # write HTTP method wrapers
    def get(%Client{} = client \\ new(), url), do: Driver.get(client.tesla, url)

    # or maybe even better write more descriptive interface
    def items(%Client{} = client), do: Driver.get(client.tesla, "/items")
  end

  test "calls work with custom client client" do
    assert %{status: 200} = ApiA.get(ApiA.new(), @url <> "/")
  end

  test "calls do not accept normal clients" do
    assert_raise FunctionClauseError, fn ->
      ApiA.get(%Tesla.Client{}, @url <> "/")
    end
  end

  test "calls defaults to the custom client" do
    assert %{status: 200} = ApiA.get(@url <> "/")
  end
end

All you need to do is to write a wrapper module that will provide the interface you need with desired pattern matching, either via exposing HTTP functions (get, post, etc) or by writing more descriptive interface mapping to specific API endpoints.

@teamon
Copy link
Member

teamon commented Mar 13, 2018

@christhekeele I'm closing this due to inactivity. Feel free to reopen/comment.

@teamon teamon closed this Mar 13, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants