I’m currently tinkering with building a Slack-facing ChatOps service for my team using clojure + polylith. On the other end of the system will be things like TeamCity, Perforce, Helix Swarm (code review platform), and various other bits and bobs. It’s going to be a bit of a dev/test/release swiss-army knife, so polylith seems like a good way to break it down by component and use-case. I’m currently trying to work out a good way to handle multiple frontends for it - it’ll need to be able to process requests via Slack websockets, a REST API, a CLI tool and some sort of scheduling mechanism (quartz?). It will also need to be able to potentially respond in kind to Slack messages or REST requests etc. Any suggestions on how best to manage this variety of interfaces? I like the idea of components for managing core logic and the interactions with backend services, but I’m not sure how to manage projects/bases in a way that allows me to deploy the app sanely with bases for each of the different frontends. Thankfully, it doesn’t need to maintain much in the way of state: just about everything it will be dealing with maintains its own state and the bot will just be coordinating between those different stores to produce useful output or trigger/report on various tasks.
Clojure + Polylith = Good choice! It sounds to me that you need four bases (if I understood you correctly):
• one that processes requests via Slack websockets
• a REST API
• a CLI tool API
• a scheduling mechanism (quartz?)
The remaining code will be distributed among various components. Everything can live in the development project to begin with, and you are not in a hurry to decide how to run your code in production.
When it's time to create production artifacts, you can create a cli-tool project (or similar name) where you put all the bricks you need for that. Probably one cli base and a number of components. You can use tools.build to build an uberjar, see an example https://github.com/polyfy/polylith/blob/205210dee83c7837be9546e12aa08707eecdd919/build.clj#L193.
You can start by combining the other three services into a single project, creating one unified service. Alternatively, you can split them into two or three separate services, depending on your requirements.
Thanks for this! I have set up a base that covers both the REST and Slack websocket APIs using Integrant, and a separate base for CLI (which will make requests via the rest api). Scheduling I’m still working on the most fitting option for our (somewhat disparate) infrastructure, but that’s a low priority.
I’m currently battling with passing big chunks of config around to different components - e.g. I have a backend that interacts with perforce via the p4 CLI tool, and I need to supply it with server hostname, auth token, etc for each operation. That’s all being supplied to the base components by integrant, but because it’s discrete operations that are just invoked directly as functions, I’m finding myself having to pass in the config blob to each function, which feels unwieldy.
Full disclosure (disclojure?): This is my first foray into anything resembling substantial software architecture in about 10 years (I’ve been doing DevOps, infrastructure-as-code, pipelines-as-code, etc ever since :D); The last time I did anything like this I was building insurance systems using http://ASP.NET MVC, SQL Server and MuleESB so try to go easy on me hehe