Daw
Daw

Reputation: 21

How should I retrieve the current user in a hexagonal architecture?

I'm designing an application using hexagonal architecture, and I need to retrieve the current user for authorization purposes. In my application layer, I have a command to delete an item, and before deleting, I need to ensure that the current user is allowed to perform the deletion.

Below is a simplified version of my command and its handler:

data class DeleteTodoCommand(val todoId: TodoId) : Command<Unit>

internal class DeleteTodoCommandHandler(
    private val todoRepository: TodoRepository,
) : CommandHandler<DeleteTodoCommand, Unit> {
    override fun handle(command: DeleteTodoCommand) {
        val todo = todoRepository.findById(command.todoId) ?: throw SomeException()
        // TODO: Retrieve the current user and perform authorization checks before deletion
        todoRepository.delete(todo)
    }
}

I've considered two potential approaches:

  1. Retrieve the user in the infrastructure layer and pass it to the application layer:
    This would involve handling user resolution (e.g., from HTTP headers or CLI context) directly within each adapter. However, this could lead to duplicating the user retrieval logic across different adapters (REST, CLI, etc.).

  2. Define a port in the application layer (e.g., CurrentUserResolver) implemented by an adapter in the infrastructure layer:
    With this approach, the application layer defines an interface for retrieving the current user. The infrastructure layer then provides the concrete implementation (e.g., via a JWT adapter or another mechanism). This decouples the user resolution logic from the adapter details and promotes a more modular design.

    My question is: Is it a good practice to treat current user retrieval as a port in hexagonal architecture?

    Any insights would be greatly appreciated.

Upvotes: 2

Views: 53

Answers (0)

Related Questions