Search code examples
c#domain-driven-designclean-architecture

How should I send HTTP Request in Clean Architecture in C#


I'm new in DDD/ Clean Architecture I'm trying to implement this architecture in a new from scratch application and I feel confused in some points. I'm trying to make the best choice to not regret it as application will start growing. Probably my question is a bit stupid, but again i'm new in DDD and trying to make the best choices.

I'm trying to stick to this example https://github.com/ardalis/CleanArchitecture from Ardalis

Here is my model/problem simplified

-ApplicationAggregateRoot

---Application

---Instance

Application has a list of Instance.

Now I have to do an HTTPRequest "/operationA" on the Instance, this can be done by my blazor UI or by my API via controllers.

The result of this HTTP Request "/operationA" will have to be saved in my repository, and do other stuff, so from what I understood here I need an event when I have the HTPP Response something like "OperationAFinishedEvent"

What I don't really know how to figure it out is how should I make this call in my controller/blazor for example.

Should I do (pseudo code):

A)

_repository.GetApplicationById(1).Instances.First(i => i == id).OperationA()

and have some event raised in OperationA() Method of Instance (something like "OperationASentEvent") which will be wired to a handler that will call _httpClient.OperationA(instance.Url)

Or should I pass by a domain service class for doing the call instead of an event like:

B)

class Controller
{
    OperationA(Instance instance)
    {
       _instanceService.OperationA(instance)
    }
}


class InstanceService
{
   void OperationA(Instance instance)
   {
     _httpClient.OperationA(instance.Url);
     new OperationAFinishedEvent(instance);
   }
}

C) Or call directly

_httpClient.OperationA(instance.Url);
new OperationAFinishedEvent(instance);

from both controller and blazor

Or maybe something else ?

Thank's


Solution

  • It sounds like you have a Blazor client side app as well as a server-side app that you access via an API. So let's address both sides of the app.

    In Blazor, you're typically going to minimize application logic and mostly just make calls to the API. So the code required to kick off an operation for an application instance in Blazor should look like this:

    var result = await _httpClient.PostAsync(endpointUrl, data);
    

    If that's a long-running process, you might bet back a result that provides you with another endpoint you can query for status. Otherwise the result should just let you know if the process completed successfully or not.

    In your API, you will have various endpoints. Normally these endpoints correspond to resources and operations you can take to alter the state of these resources. Your API resources usually correspond to your domain model, but not always 100%. You should generally avoid using HTTP APIs for Remote Procedure Call (RPC) operations, since they're not really designed for that purpose. Instead, think in terms of requests and responses, typically. Imagine you're trying to get your city government to do something, and the way you do that is by filling out a form to hand to a clerk. Then when the action has been completed, they hand you back some more paperwork. The clerk is your API. The papers are your request and response objects. The actual action - the "instance operation" is happening back inside the office where you don't see it as a client, and none of your interactions are with it directly.

    So you might have a resource like this:

    /Applications/123/Instances/234/PendingOperations

    You can list pending operations. You can POST a new operation request. Etc. There might also be a resource for .../CompletedOperations or you might get back an id for your pending operation that you can later use to view its status. The idea is to have an endpoint that represents a noun (a resource) and not a verb (do something).

    Hope that helps!