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.
- This reduces the chances of the controllers becoming bloated.
- Better structure of your project and makes it easier to navigate (file/class-names makes it instantly clear what it does).
- 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?