The Nitty-gritty

Through these services our apps would interact with the domain.Each application service class would belong to a context: Operations, Marketing, CS, Fleet, etc…Any shared logic would go to base abstract classes in the Core package.Services could throw three types of exceptions: ValidationException, BusinessException and a more specialised exception (if needed) extending BusinessException.Minimum Testing standard was created, where we’d cover the “happy path” of the business action (where everything worked and the action was successful) plus any exception the service might throw.Each service would receive a request object and return a response object..Request objects would be value objects that accepted only scalar values and perform validation..Response objects would be responsible for transformation, acting as some sort of ACL (anti-corruption layer) for the database, they’d receive data and convert the data to an array.Something like this:Let’s see how all of this translated into code, this is a simple service example:This is the service request object, where validation is performed:And the service response object where transformation is done:And finally that’s how services are used in controllers:For simple read operations we found application services to be an overkill and created “data fetchers”, which are services that don’t need neither tests or request objects.All this effort was to improve readability, increase testing coverage and stop using Eloquent directly in the apps so in the future we could evolve our data schema..But as anything in life this solution has its pros and cons:Pros:By receiving and returning scalar values to and from these services we can guarantee a sealed domain, logic cannot leak into or out of the domain.Just by looking into a service class we are able to know what’s going on..The namespace gives you the context of the service and who is using it..The data and validation on the request class tells you what the service needs to work..The logic in the service and its exceptions shows how things are done..And any data the frontend needs can be seen in the response classes.Minimum testing these application services is a joy, very easy and intuitive..Just assert the happy path and cover any exception the service might throw.Cons:The domain is a bit weird, it is composed of a hundreds of application service classes with procedural code inside..Far away from a more refined DDD domain and its tactical patterns.The deploy continues to be monolithic, any change on the DB will cause a rebuild of all apps and APIs.ConclusionKeep in mind we had to be very pragmatic with this solution, we weighed what we had to do against what could be done..We call this part of our architecture the Core and we fight tooth and nail to prevent it from growing..Any opportunity we have we decompose the Core by extracting independent services from it.. More details

Leave a Reply