{"_id":"561c8359f067153500bf6e2c","project":"56000f0d8c0c9d0d00dcad21","__v":14,"githubsync":"","version":{"_id":"56000f0e8c0c9d0d00dcad24","project":"56000f0d8c0c9d0d00dcad21","__v":13,"createdAt":"2015-09-21T14:07:10.176Z","releaseDate":"2015-09-21T14:07:10.176Z","categories":["56000f0e8c0c9d0d00dcad25","56008f2497f69f1700f21a36","560091601503430d007cc936","560e0d8054af2b0d005bbe92","560e3ce7ad6b200d00ff471c","560e3cf2c4e4ae0d00b42ed1","561c81d0e822e12b00e1fe00","561c81e9e822e12b00e1fe01","561c823d20b4a92b007d5147","56257f8951bf1c0d001f660a","562d5f165bd25e0d0054dbd4","562d68d5d38b650d0044472a","56421aebb0dc090d00f88438"],"is_deprecated":false,"is_hidden":false,"is_beta":false,"is_stable":true,"codename":"","version_clean":"1.0.0","version":"1.0"},"category":{"_id":"561c81d0e822e12b00e1fe00","__v":5,"pages":["561c8359f067153500bf6e2c","561c8433b1e87c0d00eee837","561c8502a46cd40d00b11d9d","561c85ace822e12b00e1fe0a","5625969d23053b2300f59733"],"project":"56000f0d8c0c9d0d00dcad21","version":"56000f0e8c0c9d0d00dcad24","sync":{"url":"","isSync":false},"reference":false,"createdAt":"2015-10-13T04:00:16.895Z","from_sync":false,"order":4,"slug":"spaceevent-sourcing","title":"space:event-sourcing"},"user":"5600910981a9670d006d144f","updates":[],"next":{"pages":[],"description":""},"createdAt":"2015-10-13T04:06:49.926Z","link_external":false,"link_url":"","sync_unique":"","hidden":false,"api":{"settings":"","results":{"codes":[]},"auth":"required","params":[],"url":""},"isReference":false,"order":3,"body":"Aggregates are a cluster of domain objects that are treated as a single unit where your business logic lives. How you determine the boundary of an Aggregate takes a deep understanding of the domain you're modelling, and the application of [Domain Driven Design](doc:basics). The aggregate encapsulates all Entities and Value Object that are required by it to enact on business rules, and protect against invariants. [Commands](doc:commands) are sent into the domain layer to instantiate an Aggregate object, then further commands are routed to it from the [Router](doc:router) by matching the GUID\n[block:callout]\n{\n  \"type\": \"info\",\n  \"title\": \"What's happening under the hood?\",\n  \"body\": \"An event-sourced Aggregate's state is determined by the events it generates. [Commands](doc:commands) are handled by the [Router](doc:router), either instantiating a new aggregate or rebuilding an existing one by replaying all the associated events from the Commit Store. After processing a command, the aggregate saves a new event to it's internal array, which is then committed to the Store by the [Router](doc:router), then published into the event bus for subscribers such as Process Managers, Projections for managing a View Cache in the application layer, or integration with other bounded contexts.\"\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Initializing command\"\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Command processing configuration\"\n}\n[/block]\nMap [Commands](doc:commands) passed into the aggregate by the [Router](doc:router) to a private method. \n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Business logic methods\"\n}\n[/block]\nThis is where the business rules and logic is contained. By referencing it's own state, the aggregate makes decisions, and then saves an [Events](doc:events) into the internal _events_ array with the outcome. \n[block:callout]\n{\n  \"type\": \"warning\",\n  \"title\": \"External dependencies\",\n  \"body\": \"There should be no need to rely on external dependencies within an Aggregate, as this would indicate you have an incorrect boundary defined and should consider revising your design.\"\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"info\",\n  \"title\": \"Why are these methods private?\",\n  \"body\": \"[Commands](doc:commands) in a [CQRS](doc:cqrs) system are the only public interface. The aggregate holds the configuration for mapping an incoming command to a method.\"\n}\n[/block]\n\n[block:callout]\n{\n  \"type\": \"info\",\n  \"title\": \"If the aggregate isn't publishing events, who is?\",\n  \"body\": \"The aggregate knows nothing about the infrastructure, it just knows that it receives [Commands](doc:commands) and creates [Events](doc:events). These events are published at a later stage after the changes are persisted.\"\n}\n[/block]\n\n[block:api-header]\n{\n  \"type\": \"basic\",\n  \"title\": \"Mapping events to state change\"\n}\n[/block]\nEach [Event](doc:events) the aggregate generates needs to be mapped to a state translation function.","excerpt":"Space.eventSourcing.Aggregate","slug":"aggregates","type":"basic","title":"Aggregate"}

Aggregate

Space.eventSourcing.Aggregate

Aggregates are a cluster of domain objects that are treated as a single unit where your business logic lives. How you determine the boundary of an Aggregate takes a deep understanding of the domain you're modelling, and the application of [Domain Driven Design](doc:basics). The aggregate encapsulates all Entities and Value Object that are required by it to enact on business rules, and protect against invariants. [Commands](doc:commands) are sent into the domain layer to instantiate an Aggregate object, then further commands are routed to it from the [Router](doc:router) by matching the GUID [block:callout] { "type": "info", "title": "What's happening under the hood?", "body": "An event-sourced Aggregate's state is determined by the events it generates. [Commands](doc:commands) are handled by the [Router](doc:router), either instantiating a new aggregate or rebuilding an existing one by replaying all the associated events from the Commit Store. After processing a command, the aggregate saves a new event to it's internal array, which is then committed to the Store by the [Router](doc:router), then published into the event bus for subscribers such as Process Managers, Projections for managing a View Cache in the application layer, or integration with other bounded contexts." } [/block] [block:api-header] { "type": "basic", "title": "Initializing command" } [/block] [block:api-header] { "type": "basic", "title": "Command processing configuration" } [/block] Map [Commands](doc:commands) passed into the aggregate by the [Router](doc:router) to a private method. [block:api-header] { "type": "basic", "title": "Business logic methods" } [/block] This is where the business rules and logic is contained. By referencing it's own state, the aggregate makes decisions, and then saves an [Events](doc:events) into the internal _events_ array with the outcome. [block:callout] { "type": "warning", "title": "External dependencies", "body": "There should be no need to rely on external dependencies within an Aggregate, as this would indicate you have an incorrect boundary defined and should consider revising your design." } [/block] [block:callout] { "type": "info", "title": "Why are these methods private?", "body": "[Commands](doc:commands) in a [CQRS](doc:cqrs) system are the only public interface. The aggregate holds the configuration for mapping an incoming command to a method." } [/block] [block:callout] { "type": "info", "title": "If the aggregate isn't publishing events, who is?", "body": "The aggregate knows nothing about the infrastructure, it just knows that it receives [Commands](doc:commands) and creates [Events](doc:events). These events are published at a later stage after the changes are persisted." } [/block] [block:api-header] { "type": "basic", "title": "Mapping events to state change" } [/block] Each [Event](doc:events) the aggregate generates needs to be mapped to a state translation function.