If I am developing an application using DDD, where do the infrastrucure and behavior components go? For example, user management, user specific configuration, permissions, application menuing, etc.
These components really have nothing to do with the business requirements being fullfilled by my domain, but they are still required elements of my application. Many of them also require persistance.
It's pretty normal to have non-domain components along with the domain in your project - after all not everything is business domain oriented. Where they belong actually depends on how you structure your solution. In most cases I tend to follow Onion Architecture, so all of my logic is provided by Application Services, regardless if it's domain or non-domain oriented.
Well if you find that your usecases rarely demands information from your core domain joined with application specific, you can probably split that into a separate database. Access this information through Application Service layer, since this layer is suppose to serve your application needs. If that includes user profile persistence etc, that's fine.
But you remember that if you got infrastructural failure and you want to do a rollback with some transaction logs or database backups, you'd probably want all persisted data be roll-backed. So then it's easier to have these domains share a database. Pros and cons - always compromise...
If I know that this application would have minor interaction with it's environment, I would put this in one database and let the application service layer interact with clients.
If I know that there will be several applications/clients I may consider to split database so that Webb application user specifics are stored in separate database. Very hard to say, since I have no overview of all the requirements.
/Magnus
Related
I'm trying to make a service architecture which includes two Node.js apps which shares the same database. The overall service architecture looks like below (simplified version)
I'm planning to use Sequelize as an ORM to access the database. As far as I know, if a service uses Sequelize, it needs model to get the structure of data tables. In my case, api and service will access the same database, which means they should share the same Sequelize model.
So here is the question: where should I locate the common Sequelize relevant files? It seems I have two choices:
put them on the upper common location (assuming the project structure is monorepo) so that each apps can use the single same files
maintain copies of files in each apps' project folders. In this case, each apps will be independent(Let's say I want to dockerize each apps) but in case the Sequelize files modified, the same action should be done for the other.
I'm not sure how I understood is correct. Is my question valid? If so, what is the better choice and practice? I appreciate for your answers in advance.
There is no correct answer, it depends on the specific situation, but sharing a database between multiple microservices is a bad design.
Sharing a database means tight coupling at the data level. The direct consequence is that when a service modifies the database table structure, such as deleting the name field of the user table, it may break the APIs of other services and all use the sequelize user model. All services need to update the model definition and modify the implementation code of the API.
If all of your services are maintained by a team, I suggest you choose the first solution, which costs less and is easier to maintain. If your services are maintained by different teams, the two solutions are actually similar, because as long as the table structure is modified, the application layer model needs to be modified or verified whether it still works well.
Therefore, I recommend following the best practices of microservice architecture, first splitting the database vertically according to the business model, and building application APIs on top of it.
Core principles of microservices:
loose coupling
high cohesion
Background
We are looking at porting a 'monolithic' 3 tier Web app to a microservices architecture. The web app displays listings to a consumer (think Craiglist).
The backend consists of a REST API that calls into a SQL DB and returns JSON for a SPA app to build a UI (there's also a mobile app). Data is written to the SQL DB via background services (ftp + worker roles). There's also some pages that allow writes by the user.
Information required:
I'm trying to figure out how (if at all), Azure Service Fabric would be a good fit for a microservices architecture in my scenario. I know the pros/cons of microservices vs monolith, but i'm trying to figure out the application of various microservice programming models to our current architecture.
Questions
Is Azure Service Fabric a good fit for this? If not, other recommendations? Currently i'm leaning towards a bunch of OWIN-based .NET web sites, split up by area/service, each hosted on their own machine and tied together by an API gateway.
Which Service Fabric programming model would i go for? Stateless services with their own backing DB? I can't see how Stateful or Actor model would help here.
If i went with Stateful services/Actor, how would i go about updating data as part of a maintenance/ad-hoc admin request? Traditionally we would simply login to the DB and update the data, and the API would return the new data - but if it's persisted in-memory/across nodes in a cluster, how would we update it? Would i have to expose this all via methods on the service? Similarly, how would I import my existing SQL data into a stateful service?
For Stateful services/actor model, how can I 'see' the data visually, with an object Explorer/UI. Our data is our Gold, and I'm concerned of the lack of control/visibility of it in the reliable services models
Basically, is there some documentation on the decision path towards which programming model to go for? I could model a "listing" as an Actor, and have millions of those - sure, but i could also have a Stateful service that stores the listing locally, and i could also have a Stateless service that fetches it from the DB. How does one decide as to which is the best approach, for a given use case?
Thanks.
What is it about your current setup that isn't meeting your requirements? What do you hope to gain from a more complex architecture?
Microservices aren't a magic bullet. You mainly get four benefits:
You can scale and distribute pieces of your overall system independently. Service Fabric has very sophisticated tools and advanced capabilities for this.
You can deploy and upgrade pieces of your overall system independently. Service Fabric again has advanced capabilities for this.
You can have a polyglot system - each service can be written in a different language/platform.
You can use conflicting dependencies - each service can have its own set of dependencies, like different framework versions.
All of this comes at a cost and introduces complexity and new ways your system can fail. For example: your fast, compile-time checked in-proc method calls now become slow (by comparison to an in-proc function call) failure-prone network calls. And these are not specific to Service Fabric, btw, this is just what happens you go from in-proc method calls to cross-machine I/O - doesn't matter what platform you use. The decision path here is a pro/con list specific to your application and your requirements.
To answer your Service Fabric questions specifically:
Which programming model do you go for? Start with stateless services with ASP.NET Core. It's going to be the simplest translation of your current architecture that doesn't require mucking around with your data layer.
Stateful has a lot of great uses, but it's not necessarily a replacement for your RDBMS. A good place to start is hot data that can be stored in simple key-value pairs, is accessed frequently and needs to be low-latency (you get local reads!), and doesn't need to be datamined. Some examples include user session state, cache data, a "snapshot" of the most recent items in a data stream (like the most recent stock quote in a stream of stock quotes).
Currently the only way to see or query your data is programmatically directly against the Reliable Collection APIs. There is no viewer or "management studio" tool. You have to write (and secure) an API in each service that can display and query data.
Finally, the actor model is a very niche model. It serves specific purposes but if you just treat it as a data store it will not work for you. Like in your example, a listing per actor probably wouldn't work because you can't query across that list, or even have multiple users reading the same listing simultaneously.
I am quite new to DDD and have come across a scenario that i'm not to sure how to handle.
I have an application that is used to track vehicles. This application is what will be implementing the "core" of the domain for the business i am working for. Not only is this application going to be used, there will be other utility programs that must be created and used in order to help this "core/main" application function.
for example:
there is an windows service needed that will perform configured queries on a database and return results to an external database that my routing application will use. This windows service has the concept of a QuerySettings class that can be created and is then executed by this application.
Question1:
What do you call utility applications like the above described in DDD? ( it definitely isn't the main core of the domain but it's needed in order for the core application to work )
QUestion2:
Is QuerySettings a domain model? if not what is it and where should it be placed within following the onion architecture?
For question1: You may have a look at Bounded context, I think Bounded context contains a group of Domain models that represent concepts in a subdomain(or a core domain). You may need to map or share domain models in different bounded contexts to handle your business, this depends on your bounded context strategy, share-kernal, anti-corruption-layer(to name a few).
For question2: I have little information of how QuerySettings works but in general it is a domain model but in a generic subdomain, not in your vehicle tracking core domain. In core domain's view, it maybe an infrastructure concept.
I have a Node application which persists data to a MongoDB database. Most of this data is in hand, such as data for the User collection. However, the application also has the concept of Website collection, and for this collection, data must first be downloaded from somewhere before it is saved.
I am wondering how I should separate the above concerns in my application. At the service layer, I have things like User and Website. They provide basic CRUD operations. At completely the opposite end of the spectrum, there is a user interface whereby uses can input a website URL. Somewhere between this UI and the application persisting the data to MongoDB (the service layer), the application must make a request to this URL to gather some data. Once the data has been fetched, the Website service will persist it.
Potentially, there could be thousands of these URLs entered at once, and I do not want to bring down the Node process that handles the web server due to load issues. Therefore I think it would be a good idea to abstract the work out to a different process and use some sort of messaging bus to tie the application together.
It seems that you've decomposed system correctly -and have created that separation at the persistence "service" layer-, but I'd take this separation a bit further by moving toward a distributed system architecture (i.e. SOA / micro-services).
The initial step of building a distributed system is identifying each of the functions necessary to meet the overall business goal of the application and mapping these to service endpoints. Each loosely coupled service endpoint will then serve a small isolated job/function and it will act as an abstraction for that business goal.
By continuing the separation of responsibilities all the way to the service endpoint you create small independent boundaries for scalability, throughput, fault tolerance, security, deployment, etc.
For example -RESTfully speaking-, this might mean service endpoints for both Users (e.g. /users/{userid}) and Websites (e.g. /websites/{websiteid|url})... and perhaps an additional Resource to maintain the relationship/link between the two (e.g. /users/{userid}/userwebsites : {websiteid:1234,url:blah.com).
This separation would mean you can handle the website processing responsibility independently, which would have a number of benefits -beyond just handling the different load characteristics-.
I have a system that talks with the database using repositories. What is the correct definition when it is a remote service? Or better,
Repository is for databases as [...] is for external Web-Services.
I found in many places about ServiceAgents but I don't know if this is the correct definition.
In DDD, Repositories represent a virtual collection of entities (aggregate roots in particular). So, if you have 10M persisted customers, you would work with a repository as if it were a collection of all 10M in memory. Repositories generally only deal with the same types of operations you would find on a collection: Add something, Remove something, Find something in the collection.
If the actual persistence of the data occurs via a Web Service, the implementation of the repository might interact with a Web Service proxy rather than with a database. The fact that the persistence involves a web service doesn't drive how it should be expressed by your domain however. That is to say, whether the data is persisted via direct database calls, an ORM, a Web Service, or a courier pigeon is an implementation detail.
Now, if your domain model has dependencies to be facilitated by external services (e.g. credit card validation, address verification, etc.), this should be expressed as a Domain Service in the form of an interface which defines the required operations in terms of the domain model. To be clear, Domain Services are operations which are logically part of your domain, but don't fit cleanly for some reason or another on a given entity or value object. Behavior facilitated by an external service is just one example of when you might use a Domain Service, so don't think of Domain Services as "the repository pattern for Web Services" or some such thing.
Not sure if this is the official term but I'd refer to this as a "Service Proxy".
I'm just begging to wrap my head around most of the DDD principles but my understanding is that Repositories are generally used to abstract databases but they could be used to wrap anything that behaves as persistent and/or queryable store. So in short I guess what I'm suggesting is that if your service behaves enough like a database then I don't see any problem with using a repository to abstract access to the entities that it deals with.
Otherwise, if the web service doesn't directly deal with data or behavior that is in your domain, then perhaps your case may be a candidate for an infrastructure level service in your application layer.
If anybody has any objections then please comment as I would like to know if I myself am misunderstanding the intended use of repositories.