My 3 Favourite Things From Laravel 7
Time to read: 5 minutes
Laravel 7 has released. And like any proper major release, it's packed to the rafters with new and exciting features. It's time to take a look at three of my favourite new features, and, if we're lucky, there might be a bonus feature at the end.
You’ll need some existing knowledge of PHP and a little Laravel knowledge to follow along. You can find the sample code used in this article on GitHub.
Custom Casting with Eloquent
Eloquent, Laravel's object relationship mapper is a useful tool for moving data between our database and our code. We could do some sensible type conversions using Eloquent’s Mutators
already. For example, add any field to the $dates
property of our model and it is automatically converted into a Carbon
date object for us.
Custom Casts take this a step further by helping us to decouple how our data looks in our database and our application. Often we'll want to store our data one way, and interact with it in our application another. Custom casts allow us to automatically convert data between the database state and the application state on read and write.
Let's assume we have a transactions table described by this migration:
database/migrations/create_transactions_table.php
We're storing some information about the cost of the transaction in several fields, the primary and secondary values, the currency's code, separator and symbol. This format is ok for the database, but it would be better if we could interact with currency amounts in our codebase using an Amount
value object.
app/ValueObject/Amount.php
We're using a simple object that stores our data in properties and can be cast to a string
for display. It makes sense to represent monetary amounts in value objects, and the new custom casting feature from Laravel 7 makes it so much easier for us to do just that.
Casts are PHP classes that implement the CastsAttributes
interface that prescribes get
and set
methods. The get
method is called when we want to convert from the database to our application. set
is the opposite; it's called when we want to change from our application to the database.
In our case we can create a cast to handle our money amounts:
app/Cast/AmountCast.php
We can see how our get
creates a new Amount
value object and populates it with the data from the database, while set
converts the data from that value object into a key/value pair ready for the database.
To tell Eloquent to use this cast, we add a new $casts
array property to our Transaction
model where the key is the property name, and the value is the cast to use.
app/Transaction.php
We can test this works by creating a simple route:
routes/web.php
If we hit /casts
in our application, we'll see the __toString
method of the Amount
object being run, which proves that our value object is being created by eloquent.
I'm always a fan of using value objects rather than arrays in our applications. Objects are so much less error-prone as we get completion by our editor, and also can be made immutable so we know the state can't be changed in places where it shouldn't. This is a great addition to help us to have better-architected applications.
Blade Components
Blade components let us render isolated atomic areas of our front-end with reusable components. They look a lot like components from a front-end framework like React or Vue but only use the Blade templating engine and are entirely server-side. I like these for creating reusable code to solve repeated problems.
It's common in web applications that we need to render errors from user interactions, and these are a great example of components we'll need to reuse around our front-end. We've been able to do this previously using subviews, but the new component architecture simplifies the process and brings it in line with existing front-end ideas.
We can create a new component by using the Artisan command-line tool from the root of our project:
Blade components need to extend the Component
abstract class and should implement the render
method. Let's take a look at our error component class.
app/View/Components/Error.php
A bit is going on here that's worth investigating. Any constructor arguments are handled from one of two places. In our example, we're expecting a string parameter which gets populated by the props of the template that calls this component; we'll see this later. We can also include class names as arguments, and they'll be fulfilled automatically from the container.
We're using the view
global function to render our sub-component template. Any public properties or methods of the component class are automatically made available in any view template you call.
resources/views/component/error.blade.php
The $attributes
property is automatically passed down from the parent template, while the $type
is a method of our component class that Blade has automatically made available. The $messages
property came in as a prop from our calling HTML as a property:
resources/views/components.blade.php
The message
prop is passed into the component class as a constructor argument that's set as a public property that's available in the rendered component. Phew.
Anything that helps us to remove duplication in our code and allows us to edit things in one place is a win for me. I'll be using this in my code to keep changes to one place.
New HTTP Client Wrapper
Guzzle is a fantastic HTTP client and can do any and every HTTP request you'll ever need to make. Unfortunately, the API that makes it so powerful also makes it difficult to remember how to use it to make even the simplest requests. Laravel 7's HTTP client is a convenience wrapper that lets us make the most common HTTP requests predictably and memorably.
Making a plain GET request is a one-line call, but when we want to do more complex things, it gets easier. I've lost count of the number of times I've had to look up the options array key to send data as a form post. Using the new Laravel 7 wrapper, we can call the asForm
method and then add the form fields as the second parameter.
The wrapper also gives us more comfortable ways to figure out what's going on with the responses to our requests. Unlike Guzzle, Laravel's client doesn't throw exceptions when it encounters a non-200 status code; instead, it makes the status available via helper methods like successful
or ok
. We can turn back on the default Guzzle exception behaviour if that's what we'd prefer.
The HTTP Client comes with some helpful mocking methods out of the box, so we don't have to make real requests in our tests:
All in all, I think that simplifying such a common task will save plenty of developers’ time.
BONUS: New Test Runner
Laravel 7 comes with a new test-runner that we can run using the command:
We can enjoy the swish new visuals, plus the runner halts on the first failure by default.
Get Upgrading!
There are plenty more new and exciting things in Laravel 7 and upgrading is not a huge task, so hopefully, this taster has given you the impetus to upgrade. Let me know what's your favourite feature in Laravel 7 on Twitter or in the comments below.
I can't wait to see what you build.
- Email: ghockin@twilio.com
- Twitter: @GeeH
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.