I was browsing the Laracasts forum last week and came across a post by @JeffreyWay in which he suggested using the new Laravel 4.3 form request classes as commands within the command bus architecture.
I decided that I would like to give this a try but needed a small project to test it out on. Having just finished the most recent episode of the Larabook series it was fresh in my mind and so I decided to build Larabook 2.0 using this approach.
Later in Jeffreys thread @flyingfoxx mentioned that he had updated his CommandCenter package to allow for request objects to be passed to the command bus. The command center package is strongly inspired by the commander package and using it is for the most part almost identical.
In addition to using requests in lieu of commands I rewrote the code to be more idiomatic to Laravel 4.3. This involved making use of requests, updating the app structure, using the new helper functions wherever possible, updating the blade tags etc. You can find the finished project here, it is up to date with the most recent Larabook lesson in the series (30).
Below are a few of the changes that I had to make and some of the issues I ran into whilst updating.
- The sass directory is now in resources/sass.
- There was no need to add the laracasts/validation package as we can just use the in-request validation method.
- Global exception catching goes in app/providers/ErrorServiceProvider
- We no longer need to explicitly catch validation errors as we are redirected back by default if the request validation fails
- Rather than placing our view composers in the base controller (which no longer exists in 4.3) the more idiomatic approach would be to place it in a custom service provider. I initially decided to use this approach however I was having problems caused by the order in which the service providers are called. I ended up creating a base controller and adding the view controllers back, this also had the advantage of being able to add the commander trait to just the base controller.
- Removed all requests from the http/requests directory and put them in folders that I would normally put the commands in.
Having used requests in this project, I cannot see the need to create additional command objects. The names of the requests are identical to those that I would use for my commands but also have built in validation, allowing me to sure that my commands hold the information I require.
One shortcoming is the inability to easily add extra information to the request object before we pass the request to the command bus. This means that we make more use of hidden fields to add this data into the request automatically. By doing so, it becomes possible for malicious users to manually change this data.
For example, when following a user we need the command/request to have the id of the logged in user and the id of the user to be followed. We would normally pass the logged in users id to the command in the controller however now that we are using requests we pass this into the form as a hidden field. We must now use the authorise method in the request to check to see whether the logged in users id matches that of the passed in user_id. If someone were to use this approach but without adding the check then a malicious user could follow someone on another users behalf.
I am a complete domain-driven design beginner so any comments you have would be much appreciated!