Victor Antunes B.
Victor Antunes B.

Reputation: 13

Entities can move from one use case to another using the controller?

I'm working on a project with the task of creating a route to checkout ticket purchases for events. In this scenario, I have a controller that receives the request with order data, client information, tickets, and payment details. Subsequently, I pass this request to my use cases to perform the tasks.

However, I have a use case where I create an Order, which is an entity, and I need another use case to receive the Order to validate the tickets using the Tickets entity. Later, if the validation is successful, the Order is passed to the payment use case, creating the Transaction entity. All of this is done in the same controller, somewhat like in the code below:

export class CheckoutController implements Controller {

  constructor(
   private createOrder: CreateOrder,
   private makeTicketValidate: MakeTicketValidate,
   private makePayment: MakePayment,
   ){}

  async handle (request: CheckoutController.Request): Promise<HttpResponse> {

     const order: Order = this.createOrder(request)
     // Here i receive the Order entity and step to the next use case

     const isValid: boolean = await this.makeTicketValidate(order)

     if(!isValid) {
       return badRequest()
     }
     
     const transactionId = await this.makePayment(order)

     if(!transactionId) {
       return internalServerError()
     }
    
     return ok({transactionId})
     
  }
}

Is it possible that I'm violating some principle of clean architecture in this controller?

Is passing the Order entity through the controller from one use case to another a code smell?

Is it correct to have multiple use cases in the same controller? Especially considering when a large amount of data is processed in a single action? Or should I separate them into separate controllers?

Do I need to return data through a presenter, or can I simply use the return of the use case itself in the controller to send the HTTP response to the frontend?

Thank you in advance to everyone who responded!

I've been considering using a data access object for the 'orders' entity to transfer data between the use cases.

Alternatively, I could separate the controllers to divide the responsibilities.

Upvotes: 0

Views: 70

Answers (1)

plainionist
plainionist

Reputation: 3573

You are not violating the rules of the Clean Architecture when orchestrating multiple use cases from a single controller. Alternatively you could also call only one use case from your controller and then use the second use case from the first use case.

In Clean Architecture, usually use cases consume "request models" and return "response models". However, passing entities between use cases directly can be a pragmatic decision which do not violate the rules of the Clean Architecture.

A controller acts as kind of an API from "outside" to your application logic. Therefore the main driver for separating a controller should be whether you want to provide a different API surface from your application.

Returning response models or entities from the controller or presenter directly is not recommended as this would cause your application internal design to be exposed outside (web API, web UI, test). The resulting coupling between caller/UI and the application logic makes further changes of your application logic significantly harder if not even impossible. Instead, controllers and presenters should serve as a "anti-corruption layer". (see also: https://youtu.be/iD4wns3yH44)

Upvotes: 0

Related Questions