Thanks for the suggestions!
I will most definitely put this on the road-map.
I have been looking a bit at how ecto does this with adapters. Do you have any other ideas on how to achieve this?
Maybe @benwilson512 could give some tips how to structure such a pluggable library. He mentioned some ideas in the ExAws thread. I would love a discussion about a a good architecture for a library
While I am not a specialist here, I have similar constraints for a project I’m working on, and I think the best path forward is to define a behaviour for the http calls and the json parsing, then it’s just a matter of implementing the callbacks for whatever library.
\Edit
You can then call functions from modules implementing the behaviour having said module declared eg in app env.
Benefits are : users can implement their own modules with libraries you didn’t think of at first and you can mock with mox.
Yes using a behaviour would be the most obvious way to introduce a safe level of indirection/decoupling.
This would be akin to depending on an interface in the OOP world?
The only real question is where the selection of the implementation should be done.
Using the app env seems straightforward, but it would have some drawbacks.
Passing a module atom in a Keyword list to all functions in ExBankID should be doable. But this would clutter up the library API.
Thanks for the link! And I will definitely take a look at the ExAws thread.
If you haven’t, take a look at my reply to krstfk. I would like to hear your thoughts, as well!
And I think that such a config is perfectly fine for Json and HttpClient. I don’t see any usecase where you would want to have 2 different parsers in the app, right?
You are probably right, but just like ExAws I will make all the config values overridable when invoking any of the functions in ExBankID. I have played a bit with NimbleOptions, maybe one way would be to have the schema default to whatever value is in the app env.
Ah, I built something like this, specifically BankID, when building on a product that got cancelled. Your description of the library says stateless. But if I recall correctly there is supposed to be some polling while waiting for the user to do their thing. I don’t have time to dig through your code for how you handle that right now but it seems stateful by design to me. I recall it seemed to map well to a GenServer or so.
Let me know if you want to see what I did. I think I could just open it up for reference.
Great question!
You are correct in that there is supposed to be some polling on the collect endpoint.
By design, this is not handled by this library at all.
The rationale behind this is that this library will be more useful to other developers if it doesn’t make any assumptions about what polling mechanism fits their use case.
However, I am planning on adding some functionality that would make implementing a polling mechanism almost trivial. First out will be to have ExBankID.collect be able to determine if the “BankID session” is in a collectable state. And then we will see where it goes from there.
Sure, it would be great to have a look at what you did!
I just used :httpc from Erlang for the HTTP client. I guess my design is pretty much the opposite where it all goes through a GenServer. Since you could easily implement what I’ve done as convenience options on top of your existing “simpler” design. Hope there is some interesting takeaways from what I did, I don’t remember how far I polished it
Might not have included a license, but feel free to grab whatever of course.
Thanks! This is great stuff.
For a while, I was considering implementing the default http client with :httpc as a way of not forcing unnecessary external dependencies on the library users. But that would probably not be worth the effort.
Thinking about it, it makes complete sense that any pluggable dependencies should be soft dependencies.