Currently, I am tasked with developing a route for processing ticket purchases for events. My approach involves utilizing a controller to handle incoming requests containing order data, client details, ticket information, and payment specifics. These requests are then delegated to appropriate use cases for execution.
One particular use case involves the creation of an Order entity, necessitating another use case to validate tickets using the Ticket entity. Once validation is successful, the Order is forwarded to the payment use case, resulting in the creation of a Transaction entity within the same controller structure as shown 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)
const isValid: boolean = await this.makeTicketValidate(order)
if(!isValid) {
return badRequest()
}
const transactionId = await this.makePayment(order)
if(!transactionId) {
return internalServerError()
}
return ok({transactionId})
}
}
Although the above setup works seamlessly, I am left questioning its adherence to clean architecture principles. Could passing the Order entity between use cases through the controller be considered a code smell? Should multiple use cases coexist within a single controller, particularly when dealing with a significant amount of data? Would it be beneficial to implement a presenter to manage data transmission between components, or can the controller suffice for sending HTTP responses directly to the frontend?
I genuinely appreciate any insights shared by those knowledgeable on this topic!
To optimize data transfer between use cases, one option under consideration is implementing a data access object specifically for the 'orders' entity. Alternatively, segregating controllers to distribute responsibilities might enhance overall system efficiency.