Fork me on GitHub
#polylith
<
2023-04-14
>
allandaviesza13:04:11

How does one handle components that need to talk to a database, and end up being used in two different projects? Is this something to avoid or is it manageable? What happens when a component is changed, and migrations needs to run? What runs them? Then how are deployments of separate projects handled?

Samuel Ludwig16:04:03

So, I've just started using polylith myself, and what I've opted for is abstracting database access into its own component

Samuel Ludwig16:04:00

That is: I have a mysql component, with some exposed functions that wrap some generic queries, and then lets say I have some family of things that access the Widget table: I then make a widget component, and expose functions that query that table behind the scenes (through the mysql component).

Samuel Ludwig16:04:51

Example functions would just be stuff like

(defn db [] (mysql/get-datasource-by-name :widget-db))
(defn find-by-id [id]
  (mysql/query! (db) 
    {:select [:*] :from [:widgets] :where [:= :id id]}))

;; Note that my mysql/query! function expects a honey-map, I have raw versions exposed as well

Samuel Ludwig16:04:34

And you would then access that in another component via (widget/find-by-id 42)

allandaviesza08:04:23

Thanks for this, I can see how this pattern would insulate code from db changes a bit better. I do still wonder how people have handled deployments of multiple services that depend on a component that has breaking changes, and how migrations are handled

tengstrand17:04:18

How to handle DDL changes to your database(s) and deploy your running application(s) can be tricky, whether you use Polylith or not. I think you need to execute the database upgrade script(s) before or after you deploy your affected project artefacts, depending on the options you have (whether the database change is breaking or not).

allandaviesza06:04:16

thanks, ye we've been thinking a long those lines