This code reads so beautifully, thank you for sharing this.
I’ve recently started doing clojure more seriously & it feels like i may have found a home in it. Its by far the natural feeling fp language to me & i think a lot of that comes from my preference for dynamic environments.
The use of multi methods here looks incredible too, can’t wait to start using them more in my projects.
I wonder how much more convoluted it would look like if you assumed that the datastore calls might fail. Which gets especially hairy in cases where you need to atomically do an action that is not allowed to fail in the middle, like fund transfers.
Handling these behaviors would introduce additional branches to the flow. It wouldn’t be fundamentally different than the case where payee isn’t in a system. Things that need to happen transactionally can always be handled within a particular multimethod as well. The idea here is to describe the high level process using the state machine.
Would you structure a complicated return in a ring header this way? Say in the easy case where you validate an input (or url), then build up a response, then turn that response into a set of hiccup vectors, then parse into a ring response at the end? I’ve thus far structured these as a series of pipelines. But that approach falls apart when you wish to do more complicated things, like database lookups and stores during a request.
I’d separate input validation and generating the response from the actual business logic. When the request comes in, I’d do all the validation and data massaging up front, and reject the request if its malformed. Then I’d pass around a map where I’d aggregate the data that I need. Finally, at the end I’d serialize this data into hiccup, and generate the response. As a side note, I highly recommend Reitit for doing validation and coercion. It lets you declare the shape of the request and the response, and can even produce a Swagger doc page based on that.
This code reads so beautifully, thank you for sharing this.
I’ve recently started doing clojure more seriously & it feels like i may have found a home in it. Its by far the natural feeling fp language to me & i think a lot of that comes from my preference for dynamic environments.
The use of multi methods here looks incredible too, can’t wait to start using them more in my projects.
Thanks, glad to hear this was helpful. :)
I wonder how much more convoluted it would look like if you assumed that the datastore calls might fail. Which gets especially hairy in cases where you need to atomically do an action that is not allowed to fail in the middle, like fund transfers.
Handling these behaviors would introduce additional branches to the flow. It wouldn’t be fundamentally different than the case where payee isn’t in a system. Things that need to happen transactionally can always be handled within a particular multimethod as well. The idea here is to describe the high level process using the state machine.
Would you structure a complicated return in a ring header this way? Say in the easy case where you validate an input (or url), then build up a response, then turn that response into a set of hiccup vectors, then parse into a ring response at the end? I’ve thus far structured these as a series of pipelines. But that approach falls apart when you wish to do more complicated things, like database lookups and stores during a request.
I’d separate input validation and generating the response from the actual business logic. When the request comes in, I’d do all the validation and data massaging up front, and reject the request if its malformed. Then I’d pass around a map where I’d aggregate the data that I need. Finally, at the end I’d serialize this data into hiccup, and generate the response. As a side note, I highly recommend Reitit for doing validation and coercion. It lets you declare the shape of the request and the response, and can even produce a Swagger doc page based on that.