How to avoid business logic in frontend while keeping frontend interactive - frontend

I am a DDD amateur, and I'm not sure I phrased the question correctly, or whether this even concerns DDD, but here is what has been bugging me about trying to implement DDD in my project.
Let's say my system is a sales order management system, where user can input sales orders with multiple lines for each order. Now the line amount can be in the base currency (of our client) or in a foreign currency, in which case it needs to be converted to the base currency by multiplying with a pre-determined exchange rate varying from month to month.
I think this amount conversion is a business rule and therefore should be in the domain layer. However I also want my user to be able to enter the amount in foreign currency and then have the amount in base currency automatically calculated and filled out in the form without the need to explicitly submit any data. This looks like it needs to be carried out on the frontend, and therefore violates the "no business rule in the frontend" rule.
How would you go about implementing this?

I think there are probably 3 main scenarios:
The logic already exists on the backend. In that case most obvious route when wanting to avoid duplication is to expose an API on the backend allowing the client to leverage that logic. The multi-tier interaction can usually be made almost transparent to the user assuming latency remains reasonable.
It's business logic, but the backend doesn't care. In your example, if the backend always work in a base currency (e.g. USD) and the exchange rate is only needed on the client then implement such logic in the client only. It becomes a client-specific concern. It's still business logic though (business logic is not limited to a specific tier), so it should be maintained as such in the client. For instance, keep that logic in client-side services rather than mixed with presentation concerns. Implement unit tests as well since it's core logic.
It's business logic on the backend, but there's too much latency. In that case you must duplicate as much logic as needed on the client to meet the performance goal. You could either do that manually or through code generation strategies (e.g. transpile one language to another).

Related

DDD Process Managers: Are they part of business logic?

Several sources claim that process managers do not contain any business logic. A Microsoft article for example says this:
You should not use a process manager to implement any business logic in your domain. Business logic belongs in the aggregate types.
Further up they also say this (emphasis mine):
It's important to note that the process manager does not perform any business logic. It only routes messages, and in some cases translates between message types.
However, I fail to see why translations between messages (e.g. from a domain event to a command) are not part of the business logic. You require a domain expert in order to know what the correct order of steps and the translations between them are. In some cases you also need to persist state in-between steps, and you maybe even select next steps based on some (business) condition. So not everything is a static list of given steps (although that alone I’d call business logic too).
In many ways a process manager (or saga for that matter) is just another aggregate type that persists state and may have some business invariants, in my opinion.
Assuming that we implement DDD with a hexagonal architecture, I‘d place the process manager in the application layer (not adapter!!) such that it can react to messages or be triggered by a timer. It would load a corresponding process manager aggregate via a repository and call methods on it that either set its (business) state or ask it for the next command to send (where the actual sending is done by the application layer of course). This aggregate lives in the domain layer because it does business logic.
I really don‘t understand why people make a distinction between business rules and workflow rules. If you delete everything except the domain layer, you should be able to reconstruct a working application without the need to consult a domain expert again.
I‘d be happy to get some further insight I might be missing from you guys.
A fair portion of the confusion here is a consequence of semantic diffusion.
The spelling "process manager" comes from Enterprise Integration Patterns (Hohpe and Woolf, 2003). There, it is a messaging pattern; more precisely, it is one possible specialization of a message router. The motivation for a message router is a decoupling of the sender and receiver.
If new message types are defined, new processing components are added, or routing rules change, we need to change only the Message Router logic, while all other components remain unaffected.
Process manager, in this context, refers to a specialization of message router that sits in the middle of a hub and spoke design, maintaining the state of the processing sequence and "determining the next processing step based on intermediate results".
The "process definition" is, of course, something that the business cares about -- we're passing these messages around to coordinate activities in different parts of the enterprise, after all.
And yes... this thing that maintains the "state of the processing sequence", sounds a lot like an example of a "domain entity", this is true.
BUT: it is an entity of the message routing domain; which is to say that it is bookkeeping to ensure that messages go to the right place rather than bookkeeping of business information (ie: the routing of shipping containers).
Expressed in the language of hexagonal architecture, what a process manager is doing is keeping track of messages sent to other hexagons (and, of course, the messages that they send back).
Domain logic is not only to be found in aggregates and domain services. Other places are:
Appropriately handling domain events. Domain events can be translated into one or multiple commands to aggregates; they can trigger those commands based on some condition/policy on the event itself and/or the state of other aggregates; they can inform an ongoing business process to proceed with its next step(s), and so forth. All of these things are part of domain logic.
A business process is a (potentially distributed) state machine that may involve various actors/users/systems. The allowed states and transitions between them are all a core part of the domain logic.
A saga is an eventually consistent transaction spanning multiple local or foreign aggregates that completes either successfully or compensates already executed steps in a best-effort manner. The steps that make up a saga can only be known to domain experts and thus are part of the domain logic.
The reasons why these three things are – in my opinion – mistaken as an application-layer-only concern are the following:
In order to handle a domain event, we must load and later save the affected aggregates. Because of this, the handler must also be part of the application layer. But crucially, not only. If we respect the idea behind a hexagonal architecture, then for each domain event handler residing in the application layer, there must be a corresponding one located in the domain layer. Even for the most trivial case where one domain event translates to exactly one command method invocation on some aggregate. This is probably omitted in many examples because it initially adds little value. But just imagine that later on, the translation will be based on some further business condition. Will we also just place that in the application layer handler? Remember: All of our domain logic should be in the domain layer.
A side note: Even if we respect this separation of concerns, we still have the choice of letting the domain event be handled by an aggregate itself or let it be translated into an aggregate command by a thin domain service. This choice however is based on an entirely different concern: Whether or not we want to couple aggregates more tightly. There is no right or wrong answer here. Some things just naturally are coupled more tightly while others might benefit from some extra indirection for increased flexibility.
In order to correctly implement a business process or saga, we have to take care of various application-specific concerns like message de-duplication, idempotency, retries, timeouts, logging etc. Although one might argue that the domain logic itself should be responsible for dealing with at least some of these aspects first-hand (see Vaughn Vernons excellent talk about modelling uncertainty). Remember, however, that the essence of the sequence of (allowed) steps/actions is entirely based on domain logic.
Finally, a word about coupling. In my view, there is a tendency in the community that coupling is a bad thing per-se and thus must be avoided/mitigated by all means. This might lead to solutions like placing event-command translations (remember: domain logic!) out in the adapter layer of a hexagonal/onion/clean architecture. This layers responsibility is to adapt something to something else with the same semantics/function, but with slightly different form (think power adapters). It is not the place to host any type of domain logic even if it is dead simple. Businesses have dependencies and coupling all over the place. The art is to embrace it where it actually is, and avoid it otherwise. There is a reason why we have partnership or customer/supplier relationships in DDD. And if we care about domain logic isolation, those dependencies are reflected right where they belong: In the domain layer.
A side note: An anti-corruption layer (DDD) is a valid example of an adapter. For example, it may take a bunch of remote domain events and transform/combine them in any way necessary to suit the local model. They still remain events that happened in the past, and don't just magically become commands. The transformation only changes form, not function. And it doesn't eliminate the inevitable coupling from a domain perspective. It just rephrases the same thing in a slightly different language.

How to slice down a monolith where my domain depends heavily from other domains?

I'm currently learning about Microservices because in the company where I work, we will split down our giant monolith into microservices.
We have a lot of business logic in our application, but this rules basically validate data from many different domains and act accordingly the status of this data.
Our domain has it's own data, of course, but I even dare to say we depend something like 60 ~ 70% of data from different domains, which makes our domain kind of an aggregator.
I created a little diagram to illustrate it:
So like I said before, my domain (Domain A) has a lot of business logic to validate data and status from all those different domains. And then after this validation, take the appropriate actions and save the result of it in the DB.
I feel like I hit a dead end, cause I have read a few articles how to break down a monolith, but I haven't got any good example where it explains this situation.
So I ask you guys, do you have any suggestions to tell me? :)
Thanks!
In DDD speak a bounded context approximates a microservice. The different domains in your diagram are probably going to be bounded contexts.
You most certainly do not want concepts from various BCs polluting each other as you are going to end up with quite a mess.
There is one place, however, where you may run into this and that is on integration/orchestration. Here you should approach this concern almost as a separate BC that relates to the orchestration or integration.
For instance, let's assume that you have an Assets domain and an Accounting domain. The two should know nothing about each other. However, when you decommission an asset (say some huge machine that grinds down rocks into stones) you perhaps need to have the accounting domain register some write-off value if the asset has not reached the end of its useful life. In this layer you would integrate the various bits of your process and manage the state using a process manager. Although the process manager, and related state, may belong to the Assets BC the AssetsOrchestration BC may make use of objects from both the Assets as well as the Accounting BCs. Typically you would attempt to limit that interaction to, say, messages using some messaging infrastructure but YMMV.
A good starting point may be Sam Newman's Microservice Decomposition Patterns.
About 18 minutes into the talk, Newman offers this pattern:
Within your monolith, identify the coarse modules of functionality.
Draw the dependency graph
OK, your dependency graph has cycles in it. That's no good, you want an acyclic graph. So iterate on the graph until you are able to eliminate the cycles. DO NOT PASS GO until you have this done
Identify candidate modules that have no inbound dependencies - you want the bits that nothing else depends on.
Pick one, and see if you can redesign your system to allow you to deploy that module independently of the monolith.

DDD Bounded Contexts Different Models For The Same Concept

I have an ERP project with multiple sub-domains. It is not using CQRS or domain events.
I have two sub-domains; CRM and Accounting. The customer concept needs to be modeled differently in the two sub-domains. CRM needs to know the size (number of employees) of the company but not the tax number. Accounting needs to know the tax number but not the size. The company name is needed by both sub-domains.
I am thinking of modeling both CRM Customer and Accounting Customer as entities. But then whenever a new customer is created by a CRM user, an Accounting Customer instance also needs to be created. And if a report needs information from both sub-domains, then the queries become more complicated then when you have single entity containing all the information.
Is this the way to go? Is there a better way? Does it make sense to have multiple sub-domains without utilizing domain events?
Are you sure you need DDD? The use case seems quite simple, maybe you just left out all the other complexities, but from just the info you're asking, a simple CRUD app would do. Data Centric apps, like reporting, don't need DDD. You need DDD when you must modify the data in strict ways, to maintain consistency.
If you are sure you do need DDD, then you need to understand the point of the model is to protect against the invariants of the domain. You say a CRM Customer must always have an equivalent Accounting Customer. How is this handled by the business today? How does accounting know about CRM customers? How does accounting know they're talking about the same customer as CRM? However they are doing it currently, is what you should try to model.
As an example, if they do it in real life by just letting the other one know. You could have your CRM context publish a new Customer event, and your Accounting context could react to it by creating an Accounting Customer for it.
If on the other hand, they both learn about it from something else, then maybe they both react to that other something's event.
If you don't want to use events, it could be a direct call, from the CRM context to the Accounting context. Though know that this would grow more restricted as the app grows, but if again you've got a simple domain, its no problem.
Also, querying data is not the same as modifying it. Queries should not use the domain model entities and value objects. It could, but it should not be constrained by it. That's because query is a read only operation. You need to put your data inside your domain model only when you are going to change it.

How to securely distinguish traffic from my app and browser traffic

I'm designing a game that makes queries to a database on the web. The database is fronted by a web service. For example, a request could look like this:
Endpoint: "server.com/user/UID/buygold"
POST:
amount: 100
The web service would make sure that userid has enough funds to purchase 100 gold, then would return a Boolean answer based on the success of the transaction.
However, I want to limit the amount of scripting someone could possibly do to automate gameplay. For example, they could figure out their userid and have automated tasks that buy gold for them while they are at work.
On the web services side, what are some sound security measures that I can put in place to decline all but real app traffic. Is there also a way to trump reverse engineers who will take the app apart and look for keys/certs?
I hope that this is not for a production environment, the security implications alone are mind boggling and certainly go beyond the scope of the allowed response, as it would require a rather lengthy and in depth list of requirements and recommendations, that are really contingent on many other factors that make up your web-service environment. For example, the network topology, authentication, session control and management, and various other variables all play important roles in fostering and implementing a sound cyber security counter measure.
However, assuming that you have all that taken care of, I will answer your main questions as follows:
For question:
"what are some sound security measures that I can put in place to decline all but real app traffic"
Answer:
This is one of many options out there that would address your particular concern, and that is to check for the client User-Agent header in the the request, which may appear something like this:
"Mozilla/5.0 (Macintosh; Intel Mac OS X 32.11; rv:49.0) Gecko/20122101 Firefox/42.0"
Depending on how the script is being run to automate gameplay, if it is in the form of a browser extension, then the User Agent really plays very poorly as a counter measure, if on the other hand, the script is being run directly from the client to your server (web-service), then, you can detect it right away, and there are ways to detect if someone spoofed a User Agent just to bypass this counter measure.
Another counter measure you can utilize is session management at the client level. So, this would require an architectural overview of how you implemented your particular project, but a general summary would follow a pattern like this:
Customer/GamePlayer would naturally be required to login (authentication of some sort)
The client system (which is the User Interface) that the game player is using, will have counter measures implemented in a front-end type of scripting language, i.e. Javascript or any framework that makes use of JS, such as jQuery, DoJo, etc.
Register event handlers that monitor actions, such as type of input, some Boolean logic that will follow something like this:
"if input is not from keyboard or mouse, then send flag with request"
The server/web-service will have logic to handle this request appropriately. This would be a way to catch/detect the game player after they commit the violation, used for legal reasons and such to profile evidence and such. If on the other hand you want to prevent that from happening, then, you could have some Boolean logic that goes something like this: "if input is not from the keyboard or mouse (or whatever permitted input device), then do not allow action (GamePlay), and still report back to web-server".
There are a dozen other ways, but this one seems to generally address your question, provided that you take into consideration that there are hundreds of other factors to think about, from networking level all the way to the application layer, and down to what pattern are you using for your web-service, such as whether it's a REST/API type of environment, does it follow an MVC pattern, and so on. There is no silver lining when it comes to cyber security, it's really a proactive and constant initiative on your end to ensure that all stakeholders' assets are protected, in this case, the asset is the web-service and gameplay, and the threat is the risk of gameplay tampering, that would affect the integrity of your game.
Now, regarding your second question:
" Is there also a way to trump reverse engineers who will take the app apart and look for keys/certs?"
When reverse engineers really put their mind to it, there is nothing you can really do, as whatever counter measure you may implement, they will find a workaround, that's why it's called reverse engineering, they will reverse engineer your "counter measure", so, not to be all cynical about it, you have to accept the reality that there is really no such thing as a "trump" counter measure when it comes to cyber security. You can however employ various mechanisms at both, the network layer and all the way to the application level, combined with proactive initiatives, intrusion detection, abnormal behavioral characteristics of the gameplay pattern, all will mitigate your risk; with all that said, your final frontier will be to ensure you have a good legal policy in place in your TOS (terms of service), and depending where you're hosting your web-service (geographically), you will be protected when users violate such terms, especially when you have verbiage that precludes users from attempting to reverse-engineer, tamper with gameplay scoreboards or currency, and so on.
Another good way, is to really connect with users, users are people, and people sometimes forget that they are also affecting others by their actions, so, once a user is aware of how his/her actions may negatively affect others, such as in the case of a user's actions to increase their 100 Gold, they may financially and emotionally affect others who may have put real time and effort into making this service even possible, so, a simple introductory welcome video upon signing up can do wonders for example; however, sometimes the user may not really know that they were prohibited from using auto-scripts for gameplay, or at least can raise an affirmative defense of that, so, having well published policies can really mitigate and potentially reduce altogether these types of risks. Despite the potentially optimistic outlook on users, you still have to exercise good programming practices and have security counter measures in place though.
I hope that I have given you some insight and direction to assist you with this matter, and that as you can see, it is really an involved and can be a very complicated type of process.
Good luck with your initiatives.

What to learn first, Front-end or Back-end development? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
For most of you web developing guru's my question will sound stupid, but as newbie I would like to ask if it is ok that I will have a frontend developed and only after Backend?
Also, if I will need database should I have the design of it first?
I also would like to know about the analysis part of the project. A friend in short informed me that to start the project requirements analysis (internal, technical and design) is a must. LEt's say if I want to build an social e-commerce site with ability for users to register. Can you determine a numbered list what would you do to prepare the analysis for such project (etc. 1. Database design a) prepare data models...)
I would be very happy if somebody could provide with a thorough answer.
Thank you.
Regards,
Donny
I usually decide what fields I need in the front end 1st.
Then start working on the database backend..then middle tiers with unit tests..then finally front end.
Of course, once I start work on the front end, I think of more fields or changes for the database....such is the nature of development.
I think this question is really a variation to the question whether the bottom-up or top-down design is better.
I find that it helps to do rough drafts of the front end to simulate typical usage of the site. This helps one to see required backend options one would have missed otherwise (thinking needed data).
Especially when new people are working with project, I'd suggest an incremental approach.
Pick some functionality you know you're going to need. Start with the database (SQL), then the backend code (PHP, maybe), then the web frontend (HTML). Make it as simple as possible to accomplish that one block of functionality. The order of things doesn't matter as much as just taking a small chunk at a time to work on.
Once that small part works, save a copy. Version control, even. That way, you can always return to something that worked if you screw something up tomorrow.
Then pick the next small function and add it in. I always find this very motivating; you get to see consistent improvement.
I'd probably plan ahead on the database level, because while any change to the HTML only really affects the HTML... database changes often require backend code changes which often require HTML changes, and having to redo everything is painful.
You should architect the tiers that you expect to exist in the whole system. Each tier can be parallel architected/implemented by different people, however integration points will require collaboration to decide on the contract.
There are two general interface/contract patterns:
1) Consumer/Application Needs -> interface/contract is dictated by the application and the next tier is written to conform/adapt to those needs. All of the tiers are now essentially driven by their downstream consumers. The pro is that you will likely have the most efficient and limited set of methods required, the downside is there is more work to adapt the system to other consumers.
OR
2) Service Provider -> interface/contract is dictated by a service which is designed to support a core set of common functionality that may service many apps, even some yet to be known. The application that consumes the provider must then adapt the contract's capabilities with its internal needs. The pro is that the service is more re-usable without modification, however those generalized methods will likely be a less efficient fit for any particular app's needs.
Neither of these is the perfect answer, it depends on the situation. The decision of 1 or 2 above may also differ depending on which tier connection you are working on. You could have a service with a service contract #2, an app with its own needs contract #1, then an adapter tier that maps the apps needs to the service's functionality.
Regardless of which pattern you use, the architecture of your tiers, their contracts, and how they interact with each other is more important than when you start working on any particular tier.
In general once the tier design is in place, you work on the tiers where the contracts are defined and followup on the tiers where contracts are consumed.
The question is highly subjective. In the practical reality in which we live one is limited by the customer's ability to communicate their requirements in a such a way that they can be translated into code (and of course ever expanding requirements). Medium-Larger companies have Business Analysts to perform most of these duties. As far as which tier to start the design, a DB guy will say DB, webguy will say frontend, etc...to each in accordance to their abilities.
There's no silver bullet. I recommend you readup on a few major paradigms like Agile and waterfall.

Resources