Hi
I am using protocol in hope, to write a easy testable, scalable and maintainable codes
The protocol definition and implementation looks as follow:
defmodule SapOdataService.Auth do
alias SapOdataService.Auth.UserLogin
alias SapOdataService.Auth.UserInfo
defprotocol Auth do
@moduledoc """
Protocol for SAP authentication.
"""
def sign_in(data)
end
defimpl Auth, for: UserLogin do
def sign_in(user) do
%UserInfo{firstname: "Foo", lastname: "Boo", basic_auth: "Basic FooBoo"}
end
end
end
the user login struct(user_login.ex):
defmodule SapOdataService.Auth.UserLogin do
defstruct username: nil, password: nil
@type t :: %__MODULE__{username: String.t, password: String.t}
end
the user info struct(user_info.ex):
defmodule SapOdataService.Auth.UserInfo do
defstruct firstname: nil, lastname: nil, basic_auth: nil
@type t :: %__MODULE__{firstname: String.t, lastname: String.t, basic_auth: String.t}
end
As you can see the code above, the implementation of userlogin
:
defimpl Auth, for: UserLogin do
def sign_in(user) do
%UserInfo{firstname: "Foo", lastname: "Boo", basic_auth: "Basic FooBoo"}
end
end
The sign_in
function will make a http post request to server, if the given authorization was correct or not.
For the request, I use HTTPoison
library for make a request to the server.
Supposed, in one day HTTPoison
will not exists anymore and some developers develop new HTTP client and then I have to replace HTTPoison
through new HTTP client.
My goal is, to write codes easy to scale and maintain.
I read the wonderful article about mock from José, he suggests to use protocol and pass the dependency as the parameter to function. That is the point, why I use he protocol over behaviour.
In addition, how to force the protocol definition to return particular type. In my case, I would like to do like this:
defprotocol Auth do
@moduledoc """
Protocol for SAP authentication.
"""
@spec sign_in(data) :: UserInfo.t
def sign_in(data)
end
Thanks