vardius / go-api-boilerplate

Go Server/API boilerplate using best practices DDD CQRS ES gRPC
https://go-api-boilerplate.local
MIT License
929 stars 135 forks source link

Domain validations #74

Closed bernadd closed 3 years ago

bernadd commented 3 years ago

This seems like a really nicely structured repo for using go in microservices. However from reading around on ddd - domains layer I understand that some business logic (validation/business logic) should be applied on them and it should stick inside domain/aggregate itself and I can't see any examples of domain validation in this project/structure. Lets take as example domain job with "deadline", so user cant post a job if deadline is before specific date (ie from today + 2 weeks forward). This should be "validated" in domain layer itself (not inside command handlers) as I understand or I am wrong? If yes how would we handle/return errors on this one in domain with current structure?

vardius commented 3 years ago

Example of such validation would be user email address that this repository contains.

https://github.com/vardius/go-api-boilerplate/blob/e1ea4729958030646721737b44f3d3d6c6fc8889/cmd/user/internal/domain/user/email_address.go#L42

Idea behind it is to use value object to validate the incoming data of each command, in our email address example value object EmailAddress is responsible of ensuring that its value is correct. Validation logic itself takes place during command payload being unmarshaled.

https://github.com/vardius/go-api-boilerplate/blob/master/cmd/user/internal/domain/user/email_address.go#L17

and this value object is used as a type for command properties

https://github.com/vardius/go-api-boilerplate/blob/e1ea4729958030646721737b44f3d3d6c6fc8889/cmd/user/internal/domain/user/commands.go#L159

and events

https://github.com/vardius/go-api-boilerplate/blob/e1ea4729958030646721737b44f3d3d6c6fc8889/cmd/user/internal/domain/user/events.go#L14

which in this case would ensure that event payload is correct, which might be an useful feedback while replacing events to rebuild data snapshots