Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HATEOAS REST API and Domain Driven Design, where to put the workflow logic?

This is intended as a follow up question to RESTful API: Where should I code my workflow? A brief summary of the question (adapted to fit my question a bit better) would be something like this:

Each domain object contains business logic associated with the specific object in a certain bounded context (X). The REST API contains logic to transform the result of a query or command into data sent over the wire (JSON for example). When using HATEOAS and hypermedia we want to model relationships between resources using links. But in order to determine which links that should be returned by the REST API one often need to resort to business logic / rules. The question is, where do these "workflow rules" belong in a DDD application? Would they perhaps be in a different bounded context dealing only with the workflow rules (perhaps in a "partner"-like relationship with X) or would they belong in the X BC?

like image 908
Johan Avatar asked May 24 '15 14:05

Johan


1 Answers

I'm not a DDD expert (only through 100 pages in Eric Evan's book) but I can tell you what happened in our case of a e-commerce catalog.

Initially we had such business flow in the same bounded context of the app based on data and the requesting user's roles/permissions we altered the state transitions (you said links, but this is really the heart of it, links are just one way to present state transitions) presented to the user. This worked ok, but it was a lot of repeated logic being executed. Then we added a search application that was a different bounded context as it presented the same data but in different collections/groupings and we didn't want to have them get out of sync.

We moved to a CQRS implementation, so a lot of our business logic is "pre-calculated" thus it's in something like a "partner context" as part of our projection from write model to read model. We don't store the links specifically, but instead flag allowed behaviours on the data. Both the catalog application and search application use this read model and it's behaviour flags to determine state transitions to present to the client.

Some stuff happens on the fly upon requesting of the resource, almost at the serialization step. We've targeted these to be moved to the pre-calculated as much as possible, but what we can't precalculate (only because of the scale) is stuff that is based specifically on the user. Like the recommended search which uses BI data within the search engine to return results. We could pre-calculate that for every single user, but the numbers are too huge for our systems right now. So we send the main apps calculated resource (from the main context) and pass it through yet another partner context to further refine things.

another use case is some links are only presented to authenticated user, and thus are hidden from anonymous users. We do this in the main apps context but it's starting to be a bit of a hindrance because their presence indicates what the user behind the request can do in other apps (like change password), and our context isn't really the authority of what the user can do in some other app. It would be nicer to hand the resource off to their context and have them process it before we return it to the user. One simple solution we used for this was instead of deep linking to functions within the external context, we link to a root resource of that context and allow it present state transitions. It means there's 2 requests, but it cleans up the locations/authorities of the logic.

like image 91
Chris DaMour Avatar answered Oct 23 '22 13:10

Chris DaMour