Fork me on GitHub
#polylith
<
2021-11-15
>
Albert04:11:36

A small question about the great example https://github.com/seancorfield/usermanager-example The app-state should be a component or project? Since it could have different app-state if we have multi project using the same code. e.g. I have a new schedule job projects/usermanager-email-notification-scheduler which is a separate deployment artifact, I might not need the same configuration that used in the projects/usermanager .

seancorfield04:11:46

You could have multiple components that implement that same interface and each project could choose which to use.

seancorfield04:11:56

At work, we have multiple http-client components with the same interface. One is an implementation based on httpkit, one based on Hato.

Eugen10:11:22

hi, we are evaluating polylith and I have some questions that I decided to ask and maybe get some answers.

Eugen10:11:21

how does it work with stuart siera components or integrant ?

furkan3ayraktar11:11:20

Polylith does not do anything around state management, you need to manage it yourself in a way that fits you the best. You can choose component, integrant, mount or any other state management library. I know that @U04V70XH6 is using component together with Polylith and he is happy with that. We are using mount at work.

Eugen11:11:52

at what level do you use them?

Eugen11:11:35

btw, thanks for getting back

furkan3ayraktar11:11:07

No worries! I’m happy to answer your questions. Some of our Polylith components requires internal state, which sometimes depends on some other components state, in turn, it needs to be coordinated. Then, what we do is, we define the components state within their implementation and expose functions in the interface, if it’s necessary, to access that state.

👍 1
seancorfield19:11:19

@U011NGC5FFY Happy to answer any specific questions you have about Component usage with Polylith. My user-manager example repo has a Polylith branch with an example of Component for application state. You can see the components interface here: https://github.com/seancorfield/usermanager-example/blob/polylith/components/app-state/src/usermanager/app_state/interface.clj -- so the actual Component machinery (lifecycle) is hidden in the implementation.

Eugen19:11:26

thanks for chipping in, now we are evaluating polilith - working on a large code base that has been developed for over 5 years now

Eugen19:11:04

I would love to see some structure and smaller, independent code bases

Ron Lusk20:12:43

Integrant is new to me (I’ve been using @U0541KMAZ ' mount for some time now), but Polylith makes it… interesting. I’m probably doing my database brick correctly: returning a connectable of some sort; and my app-URL brick less correctly: loading a base URL from a config into an atom used for URL generation. However, either way, one minor issue is Integrant’s load-namespace method: because all access goes through my.ns.my-brick.interface, I have to have configuration keys like :my.ns.my-brick.interface/foo or :my.ns.my-brick/interface to make that work. But the core code can’t require the interface, so it has to spell out the full qualified keyword, rather than use ::foo or whatever.

Eugen10:11:18

@furkan3ayraktar I don't understand why there are no dependencies between components. Article component depends on the db component but that one is not available in deps.edn of articles. https://github.com/furkan3ayraktar/clojure-polylith-realworld-example-app/blob/master/components/article/src/clojure/realworld/article/store.clj

furkan3ayraktar11:11:57

The reason that components don’t have dependencies between is that they are individual building blocks, like lego bricks, with their own external dependencies. The internal dependencies between components are via their interfaces, not implementations. Defining a specific component dependency would break that principle and take away the ability to replace components. You could have two components that implements the same interface and different projects could choose whichever of those different implementations. The component that consumes the interface doesn’t need to know which implementation is used. @U04V70XH6 explains how they use it https://clojurians.slack.com/archives/C013B7MQHJQ/p1636389094211500?thread_ts=1636379842.209500&amp;cid=C013B7MQHJQ. Internal dependencies are resolved when you put bricks together within a project. A projects configuration defines which components and base go together and if you are using poly CLI, it warns you in case of missing dependencies. If you are not using the CLI, you’ll probably notice the missing components during compile time.

👍 1
seancorfield19:11:03

@U011NGC5FFY I also blogged about that -- see the Polylith &amp; Swappable Implementations section of https://corfield.org/blog/2021/10/13/deps-edn-monorepo-7/

Eugen19:11:56

thanks, I will take a look

Eugen19:11:19

also need to convince people this is worth investing time and effort into

Eugen19:11:25

to me it makes sense, but ..

Stefan06:11:44

@U011NGC5FFY We’re now also in the process of migrating a legacy codebase to polylith. Of course I don’t know where you expect potential resistance to focus, but it’s quite doable to do the migration in “baby steps” over a large period of time. We basically converted three separate clojure projects (“common” library, “service one” and “service two”) into three big components. That immediately gave us the ability to run the two services in one single REPL, which is huge for us in terms of development experience. And now we’re slowly extracting components as we go. It’s going quite well I have to say.

polylith 2
💪 2
robert-stuttaford07:11:23

we'll be doing similarly. 35 systems across four service projects and one library project

robert-stuttaford07:11:00

will start with 1 component and 4 fat bases, and a mega-crap-ton-big interface in the component 😅 and then refactor piece by slow, careful piece from there

💪 1
1
Eugen10:11:38

aslo why is there a mix of API and implementation ?

furkan3ayraktar11:11:59

I didn’t understand this question. Could you elaborate on when you say “mix of API and implementation”?

Eugen11:11:18

the interface is the API and it is mixed with the implementation

Eugen11:11:50

you could probably split the interface and add it as a dependency

Eugen11:11:22

in Java tbis is normally the case

furkan3ayraktar12:11:12

I think you shouldn’t think about this from an OO perspective. Polylith interfaces are functional interfaces, they are functions that delegate to the implementation and you do not instantiate any objects. You can think of a Polylith interface in Java as a class with full of static functions that delegates to the interface.

furkan3ayraktar12:11:28

There are some FAQ around the interface topic on this page: https://polylith.gitbook.io/polylith/conclusion/faq

Eugen12:11:34

thanks, it's what we imagined as well, thanks for confirming

👍 1
wagjo18:11:18

Is it idiomatic for components to have some implementation specific functions that are called from the base, (e.g. different implementations may have different way to initialize themselves), or we should strive to put everything into interfaces?

furkan3ayraktar07:11:54

Componets and bases can only access other componets and bases via their interfaces. Otherwise, poly CLI will present you an error. If there are slight changes between different implementations of an interface, it could be an idea to have overloads of a function or some extra functions in the interface that one implementation could skip implementing and just return nil?

👍 1