1

I have a service(webservice) that is used to access to the domain logic. One of the methods of the webservice is createFoo, where Foo is my aggregate. So the class that implements the webservice's method calls my application service that contains the createFoo method which is responsible of doing some stuff and persisting the new Foo instance.

This new Foo instance the is returned by the application service to the class that implements the web service's method. Finally, the Foo instance is converted to something like FooWsResponse and then the web service returns the FooWsResponse instance.

Right now all this is more or less implemented like this:

public class CreateFooService{

    private FooService appService;

    private Converter<Foo, FooWsResponse> converter;

    public FooWsResponse createFoo(CreateFooParams params){
        Foo foo = FooFactory.createFoo(params);
        foo = appService.createFoo(foo);
        return converter.converter(foo);
    }
}

The problem with the code above is that the Application Service method is misleading because is not creating a Foo instance, is only working on the domain logic associated to the creation of Foo and persisting the instance.

So, the things that I want to know are:

  1. Is it ok create the aggregate outside the service layer?. I know that I can pass the CreateFooParams as parameter appService.createFoo but I don't want to do this because my service layer will be coupled to the web service framework. Also, I don't want to pass all the properties of the class CreateFooParams as parameters of appService.createFoo because I will end with a method with 15 parameters!. Finally, creating the Foo instance before calling appService.createFoo method but now the method's name is not accurate and also all clients of my appService should need to create how to create an instance of Foo to pass it as parameter of appService.createFoo which is very bad and may lead to many issues.
  2. Should I create a FooDto that receives all the data of CreateFooParams and pass it to appService.createFoo method?. This looks like a better option but having 3 different classes with almost the same properties feels very redundant

I want to know what is the right thing to do according to the DDD guidelines.

Thanks for your help.

1

Generally, I'd say no. Aggregates should not leave your domain model boundary and any business logic related to creating that aggregate should reside within that aggregate.
I'd advise you to add a factory method to that aggregate class which takes in all the necessary parameters to create a new instance of that aggregate. If there's business logic related to that creation, it should reside in that factory method.
If you feel that you need way to many parameters for that factory method, then maybe that's a sign that that aggregate could be too big (maybe).

I don't really understand why you would create and then immediately return that instance though. Usually, you separate your reads and writes, because your read and write model are usually very different.

  • Where should I call this factory?, inside the application service? I don't really understand why... Because I should return an instance of Foo that contains the id of Foo plus. – Orposuser Nov 18 '13 at 23:21
  • Where? In this case, probably in your fooservice. Why? Why do you wish to put logic about instantiating an aggregate and all the possible business logic that that entails, in another place than said aggregate? Ah id generation. Especially in DDD apps (but frankly in general as well), I would strongly advise you to generate your ids clientside, because that will save you a lot of unnecessary roundtrips and will make things much easier for you. If you use Guids for ids, you will have that flexibility. – Stefan Billiet Nov 19 '13 at 7:23
  • I agree on calling the factory from foo service that makes sense because: 1) hide the creation details from clients of the application service, 2) that will bring flexibility because clients doesn't need to know about how to create the aggregate. The id generation can be discussed in another topic but looks not desirable to me because 1)if the clients generates ids then they need to know about the internals of my domain logic and 2)also I could have some collision of ids if id generation is poorly implemented, finally 3)breaks encapsulation – Orposuser Nov 19 '13 at 17:55
  • About early id generation: 1)No they don't. Generally, you use Guids for that and Guids are for all intents and purposes in this context unique. So in Java, you have UUID.randomUUID(). JS has github.com/broofa/node-uuid. 2)See number 1 3)See number 1. Frankly in my experience, you need early id generation, because you need ids for sending commands that touch multiple entities. Otherwise it becomes very hard to build any sort of dynamic application without a gazillion roundtrips to the server. Not to mention the fact that creating something should not return anything (according to CQS). – Stefan Billiet Nov 20 '13 at 7:45
  • About CQS, AKA CQRS, that's pretty true for most of the scenarios however you still want to return an id, if generated internally so your client can use it as identifier. Agree on the early id generation but, like with any technique, one should apply on a case by case basis – Orposuser Nov 21 '13 at 5:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.