Using single action controllers in Rust?

In PHP web-frameworks like Laravel or Symfony it is favored to use Single Action Controllers. This are - like the name suggests - controllers who are responsible for only one action. This in contrast with a controller with multiple actions.

Consider this controller:

class UserController extends AbstractController
{
    // Register
    public function register(Request $request, UserPasswordEncoderInterface $passwordEncoder): Response {.... }

    // Login
    public function login(AuthenticationUtils $authenticationUtils): Response { ... }
    
    // Reset password
    public function resetPassword(Request $request, UserRepository $userRepository, UserPasswordEncoderInterface $passwordEncoder, $token): Response { ... }
}

Over time your controllers can become bloated, to avoid this we split the actions in multiple controllers. Specifically in PHP we would use the __invoke magic method and by injecting the dependency in the controller. The following controller is only responsible for logging in the user.

class UserLoginController extends AbstractController
{
    public function __construct(private AuthenticationUtils $authenticationUtils) { ... }
    
    // Login
    public function __invoke(Request $request): Response { ... }
}

In some cases the single action controller extends a base class with abstract functions to validate or authorize the request. Like in this example.

  1. This reduces the chances of the controllers becoming bloated.
  2. Better structure of your project and makes it easier to navigate (file/class-names makes it instantly clear what it does).
  3. Single Responsibility Principle applies.

But I haven't really seen this principle being used in Rust. Why exactly is that? Do you think applying this principle to Rust projects using web-frameworks like Actix-web is a good idea? Why or why not?

Code organization is not written in stone. It varies depending on the complexity of your logic:

  • If it's simple, keeping it close makes sense.
  • It it's complicated, consider splitting it.

And... that's it. Don't make a mountain out of a molehill.

2 Likes