Fork me on GitHub
#polylith
<
2022-03-30
>
jeroenvandijk14:03:55

Maybe an interesting challenge for polylith?

šŸ‘ 1
seancorfield16:03:33

We specifically do this at work with an http-client interface and implementation components for http-client-hato and http-client-httpkit (and profiles to select the implementation in :dev). I've written about it on my blog.

mynomoto17:03:00

Any chance to open source it? šŸ˜‰

mynomoto17:03:08

But thinking about, I'm not sure if this is what I described. You probably have functions that are replaced depending on the component. I wanted to have a common protocol an pass the desired implementation (a record or a reified map) so the user doesn't have to bring another http library to use some service client. Certainly the code you have could be a good base as you described making both clients behave in the same way.

seancorfield19:03:36

The API (which could be a protocol) is very simple: a function for each HTTP verb, plus a couple of small helpers. Each verb function takes a URL and optionally a hash map of options and optionally a callback function (mostly needed for async but is sometimes useful for response processing in general). The implementations are pretty simple, except for managing the sync/async defaults and mapping the options to the specific library. We have no interest in open sourcing it because although it's a small, straightforward piece of code, we don't want to have to document and maintain it for other users, and we don't care about HTTP clients beyond Hato or HttpKit (and, at some point fairly soon, we expect to stop caring about HttpKit and delete that implementation).

seancorfield19:03:51

The only reason we've done it at all is that we had two legacy apps that had to run on JDK8 and therefore couldn't use Hato (JDK11). Now we only have one of those -- we've rewritten the other fully in Clojure -- and we expect to rewrite the other one "soon".

seancorfield19:03:22

(so then we'd be in a situation where we only have a wrapper for Hato and wouldn't even want the protocol or swappable implementations)

mynomoto21:03:19

All of that makes sense. The user case I was thinking is for library writers to use the protocol and the library users then pick the desired http client implementation so you don't end with multiple http clients in the project. I think that if the poly components are published with the same artifact and the version is used to identify the client it could work, but I'm not sure if this is a good idea.

seancorfield21:03:54

@U05094X3J Each client would need an adapter that implemented the protocol -- so it would likely fall to the maintainer of the protocol to do that, or at least users would likely expect that to be the case -- and the protocol (and the various implementations) would need to be able to satisfy the needs of arbitrary libraries out there. I suspect it's a lot to ask since it would require such close collaboration between multiple library authors...

mynomoto21:03:22

Yeah, while I would love to have that, but it looks hard to make it happen.

jeroenvandijk07:03:14

@U05094X3J Maybe it only takes one library author to get it right and this approach would be adopted/copied. Do you know of libraries that could benefit from this? For instance, I was trying the juxt/apex some time ago, but i couldn't use it (directly) because it was using newer jdk classes for the http requests. If http was abstracted here this would have been a lesser problem if any. By making a list of libraries we might be able to find a proper model for this

mynomoto13:03:33

@U0FT7SRLP One example is telegram bot libraries in general, a couple of examples that use clj-http. ā€¢ https://github.com/wdhowe/telegrambot-lib ā€¢ https://github.com/Otann/morse I think that aws clients and json serialization are other candidates for this approach. Was there an index of libraries and dependencies somewhere? Looking for libraries that depend on different http clients should give us a range of usages. The telegram ones are quite simple.

seancorfield16:03:33

We specifically do this at work with an http-client interface and implementation components for http-client-hato and http-client-httpkit (and profiles to select the implementation in :dev). I've written about it on my blog.