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

This is seen as the next question for the RESTful API: where should I code my workflow? A brief summary of the question (adapted for my question is slightly better) would be something like this:

Each domain object contains business logic associated with a particular object in a specific limited context (X). The REST API contains logic for converting the result of a request or command into data sent over the wire (for example, JSON). When using HATEOAS and hypermedia, we want to model the relationship between resources using links. But in order to determine which links should be returned by the REST API, one often has to resort to business logic / rules. The question is, where do these “workflow rules" refer to the DDD application? Perhaps they would be in another limited context, dealing only with the rules of the workflow (perhaps in a "partnership" with X) or would they belong to X BC?

+5
source share
3 answers

I am not a DDD expert (only after 100 pages in Eric Evan’s book), but I can tell you what happened in our case with the e-commerce catalog.

Initially, we had such a business stream in the same limited application context, based on data and requesting user roles / permissions that we changed state transitions (you said links, but this is really his heart, links are just one way of presenting state transitions) presented to the user. This worked fine, but there was a lot of repeating logic. Then we added a search application, which was another limited context, because it represented the same data, but in different collections / groups, and we did not want them to go out of sync.

We moved on to the implementation of CQRS, so most of our business logic is “pre-calculated”, so it somewhat resembles the “partner context” as part of our projection from the recording model to the reading model. We do not store links specifically, but instead allow behavior on the data. Both the catalog application and the search application use this reading model and behavior flags to determine state transitions for presentation to the client.

Some things happen on the fly when a resource is requested, almost at the serialization stage. We aimed them to be as calculated as possible, but what we cannot pre-calculate (just because of scale) is material based solely on the user. Like the recommended search, which uses BI data in the search engine to return results. We could pre-calculate this for each individual user, but the numbers are too large for our systems right now. Therefore, we send the main resource, designed for applications (from the main context), and pass it through another partner context for further clarification.

another use case - some links are provided only to an authenticated user and, thus, are hidden from anonymous users. We do this in the main context of applications, but this is starting to hinder a little, because their presence indicates what the user behind the request can do in other applications (for example, change the password), and our context is not really the authority that the user can do this in another application. It would be better to pass the resource into their context and force them to process it before we return it to the user. One simple solution that we used for this was that instead of deeply binding to functions in an external context, we contact the root resource of this context and allow it to represent transition states. This means that there are 2 requests, but it clears the places / powers of the logic.

0
source

The workflow actually consists of domain knowledge and hate infrastructure.

If the application is not built with hypermedia, you may not even need some hate. But domain knowledge still exists, they just live in the minds of end users. To test a user command, domain knowledge is required if they forget it.

So, for hate, I divided the implementation of the workflow into two parts: domain models and the hate infrastructure.

Domain models report domain knowledge.
The hate infrastructure, on the other hand, is hate-specific, leading them out of the domain.

Here is a java example using springframework-hateoas. I put the workflow in the process of mapping domain models to resources.

@Component public class OrderResourceAssembler extends ResourceAssemblerSupport<Order, OrderResource> { @Override public OrderResource toResource(Order model) { OrderResource resource = mapToResource(model); resource.add(orderResourceHref(model).withSelfRel());//add self link if (model.isAvailableToCancel()) { //let the model tell //add cancel link resource.add(orderResourceHref(model).withRel("cancel")); } if (model.isAvailableToPay()) { //let the model tell //add payment link resource.add(new Link("http://www.restfriedchicken.com/online-txn/" + model.getTrackingId(), "payment")); } //etc return resource; } // omitted codes } 

If the model cannot say by itself, you can enter a specification object to complete the task.

0
source

Wherever a resource is located, this is the same place that is necessary to marshal access to it.

Say you have a larger system with three limited contexts: employee management, customer consumption, and service provision.

GET employee information from employee management? The decision about whether to display a link that can be used for POST or DELETE is for employee management.

GET the customer service contract you just submitted? The decision whether to show a link that can be used to reprogram the revision or POST details is for the client to make the decision. Of course, the management of the staff manages the provision of roles necessary for working with new service contracts, but customer service is responsible for knowing the requirements and other conditions and ultimately ensures that everything is checked.

Likewise, GET a profile of physical installation software from service provision? To provide services, you need to make sure that everything is in order with other services / contexts (a paid client account, the current user in the role of network services, the device is not blocked for maintenance) before it issues a link in which you can PUT a new quality of service specifications.

These “workflow” decisions are an integral part of each context — they cannot be separated elsewhere.

0
source

All Articles