{"id":5129,"date":"2020-03-05T09:42:52","date_gmt":"2020-03-05T09:42:52","guid":{"rendered":"https:\/\/www.fastcomet.com\/blog\/?p=5129"},"modified":"2022-06-09T19:56:51","modified_gmt":"2022-06-09T19:56:51","slug":"laravel-7-0-is-here","status":"publish","type":"post","link":"https:\/\/www.fastcomet.com\/blog\/laravel-7-0-is-here","title":{"rendered":"Laravel 7.0 is Here, Introducing Airlock (Sanctum)"},"content":{"rendered":"\n<p class=\"has-drop-cap\">Spring is almost here, but Laravel 7 couldn&#8217;t wait for it. Six months after <a href=\"https:\/\/www.fastcomet.com\/blog\/laravel-6-0-is-here\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">Laravel 6<\/a>, the next major release is out now and continues with its awesome new features and improvements. After version 6, <strong>Laravel is now following semver<\/strong> and will release a major version every six months. In this post, we will cover the essential features and improvements that come with Laravel 7.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p><strong>Table of Contents:<\/strong><\/p>\n\n\n\n<ul class=\"nav-list wp-block-list\"><li><a href=\"#quick-preview-of-laravel-7-0\">A Quick Preview of Laravel 7.0<\/a><\/li><li><a href=\"#laravel-airlock\">Laravel Airlock (Sanctum)<\/a><ul><li><a href=\"#api-tokens\">API tokens<\/a><\/li><li><a href=\"#spa-authentication\">SPA Authentication<\/a><\/li><\/ul><\/li><li><a href=\"#custom-eloquent-casts\">Custom Eloquent Casts<\/a><\/li><li><a href=\"#blade-component-tags-and-improvements\">Blade Component Tags and Improvements<\/a><\/li><li><a href=\"#http-client\">HTTP Client<\/a><\/li><li><a href=\"#fluent-string-operations\">Fluent String Operations<\/a><\/li><li><a href=\"#improvements-in-route-model-binding\">Improvements in Route Model Binding<\/a><ul><li><a href=\"#key-customization\">Key Customization<\/a><\/li><li><a href=\"#automatic-scoping\">Automatic Scoping<\/a><\/li><\/ul><\/li><li><a href=\"#speed-improvements-in-route-caching\">Speed Improvements in Route Caching<\/a><\/li><li><a href=\"#cors-support\">CORS Support<\/a><\/li><li><a href=\"#artisan-command\">Artisan Command<\/a><\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"quick-preview-of-laravel-7-0\">A Quick Preview of Laravel 7.0<\/h2>\n\n\n\n<p>Laravel 7 keeps with the improvements and doesn&#8217;t seem to slow down in any way. The new major version includes Laravel Airlock, custom Eloquent casts, Blade component tags, better routing speed, a new HTTP client, fluent string operations, CORS support, Speed improvements in Route Caching, Artisan test command, and many more features.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"laravel-airlock\">Laravel Airlock (Sanctum)<\/h2>\n\n\n\n<p>Laravel Airlock (now known as Sanctum) offers a featherweight authentication system for single-page applications (SPAs), mobile apps, as well as simple, token-based APIs. Airlock offers all of your application users the capability to generate multiple API tokens for their accounts. Those tokens can be granted abilities that specify all actions that the tokens may perform.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"api-tokens\">API tokens<\/h3>\n\n\n\n<p>Laravel Airlock is here mainly to solve two problems. First and foremost, it&#8217;s <strong>a simple package that issues API tokens<\/strong> to your users. This particular feature is inspired by GitHub &#8220;access tokens.&#8221; For example, if the &#8220;account settings&#8221; of your app has a screen for users to generate API tokens for their accounts, Airlock can be used to generate and manage those tokens. Such tokens usually have an extensive expiration time, but the user can revoke them whenever they wish.<\/p>\n\n\n\n<p>Airlock offers the feature via storing user API tokens in a database table, authenticating incoming requests through the <strong>Authorization header<\/strong>, which contains a valid API token.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"spa-authentication\">SPA Authentication<\/h3>\n\n\n\n<p>If you are going to use Laravel Airlock, you are not obligated in any way to use it for both API token authentication and SPA Authentication. You can use it only for one of the features, and you will still be benefiting when it comes to convenience.<\/p>\n\n\n\n<p>With that said, the second feature Airlock offers is a simple way to authenticate single-page applications (<strong>SPAs<\/strong>) that have to communicate with an API, powered by Laravel. These SPAs could exist <strong>in the same repository as your actual Laravel application<\/strong>, or they might be a completely separate repository, such as SPAs that are created using Vue CLI.<\/p>\n\n\n\n<p>For the SPA Authentication feature, Airlock doesn&#8217;t use any tokens. Instead, it uses the built-in cookie-based session authentication services that Laravel has. That offers benefits such as <strong>CSRF protection<\/strong>, <strong>session authentication<\/strong>, in addition to <strong>protecting against authentication credentials leakages<\/strong>. Laravel Airlock will attempt to use cookies for authentication only if the incoming request comes from your own SPA frontend.<\/p>\n\n\n\n<p>For more information on Laravel Airlock, consult the official <a href=\"https:\/\/laravel.com\/docs\/master\/sanctum\" target=\"_blank\" rel=\"noreferrer noopener\">Airlock documentation<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"custom-eloquent-casts\">Custom Eloquent Casts<\/h2>\n\n\n\n<p>You probably know that Laravel has a variety of helpful cast types. However, you may still occasionally have to define your own cast types. Now, you can accomplish that goal by defining a class that puts the <code>CastsAttributes<\/code> interface to use.<\/p>\n\n\n\n<p>Classes implementing this interface have to define a <code>get<\/code> and <code>set<\/code> method. The <code>get<\/code> method is to transform a raw value from the database into a cast value, and the <code>set<\/code> method has to transform a cast value into a raw value, which can be stored in the database.<\/p>\n\n\n\n<p>Here is an example, where we are going to re-implement the built-in <code>json<\/code> cast type as a custom cast type:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>&lt;?php<\/strong><br>namespace App\\Casts;<br>use Illuminate\\Contracts\\Database\\Eloquent\\CastsAttributes;<br>class Json implements CastsAttributes<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;\/**<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Cast the given value.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @param \\Illuminate\\Database\\Eloquent\\Model $model<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @param string $key<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @param mixed $value<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @param array $attributes<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @return array<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*\/<br>&nbsp;&nbsp;&nbsp;&nbsp;public function get($model, $key, $value, $attributes)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return json_decode($value, true);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;\/**<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Prepare the given value for storage.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @param \\Illuminate\\Database\\Eloquent\\Model $model<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @param string $key<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @param array $value<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @param array $attributes<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @return string<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*\/<br>&nbsp;&nbsp;&nbsp;&nbsp;public function set($model, $key, $value, $attributes)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return json_encode($value);<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>}<br><\/pre>\n\n\n\n<p>After you have a defined custom cast type, you can attach it to a model attribute by using its class name:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>&lt;?php<\/strong><br>namespace App;<br>use App\\Casts\\Json;<br>use Illuminate\\Database\\Eloquent\\Model;<br>class User extends Model<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;\/**<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* The attributes that should be cast to native types.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @var array<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*\/<br>&nbsp;&nbsp;&nbsp;&nbsp;protected $casts = [<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'options' =&gt; Json::class,<br>&nbsp;&nbsp;&nbsp;&nbsp;];<br>}<\/pre>\n\n\n\n<p>In case you want to learn how to write custom Eloquent casts, you can check the official <a rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\" href=\"https:\/\/laravel.com\/docs\/master\/eloquent-mutators#custom-casts\" target=\"_blank\">Eloquent documentation<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"blade-component-tags-and-improvements\">Blade Component Tags and Improvements<\/h2>\n\n\n\n<p>Blade components got an overhaul and now allow tag-based rendering, attribute management, component classes, inline new components, etc. As you can see, the Blade components overhaul is quite extensive, so if you want thorough information on the matter, you can go ahead and check the full <a href=\"https:\/\/laravel.com\/docs\/master\/blade#components\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">Blade component documentation<\/a>.<\/p>\n\n\n\n<p>To sum it up, now a component can have an associated class that specifies the data it accepts. All of the public properties and methods that are defined on a component class would automatically be made available to the component view. You can use the included $attribute variable (which is a bag instance) to manage all extra HTML attributes that are specified on the component.<\/p>\n\n\n\n<p>Here&#8217;s an example, where it&#8217;s assumed that an <code>App\\View\\Components\\Alert<\/code> component has been defined in such manner:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"><strong>&lt;?php<\/strong><br>namespace App\\View\\Components;<br>use Illuminate\\View\\Component;<br>class Alert extends Component<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;\/**<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* The alert type.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @var string<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*\/<br>&nbsp;&nbsp;&nbsp;&nbsp;public $type;<br>&nbsp;&nbsp;&nbsp;&nbsp;\/**<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Create the component instance.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @param string $type<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @return void<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*\/<br>&nbsp;&nbsp;&nbsp;&nbsp;public function __construct($type)<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$this-&gt;type = $type;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;\/**&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;  * Get the class for the given alert type.<br>&nbsp;&nbsp; &nbsp; *<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @return string<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*\/<br>&nbsp;&nbsp;&nbsp;&nbsp;public function classForType()<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $this-&gt;type == 'danger' ? 'alert-danger' : 'alert-warning';<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;\/**<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* Get the view \/ contents that represent the component.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;* @return \\Illuminate\\View\\View|string<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*\/<br>&nbsp;&nbsp;&nbsp;&nbsp;public function render()<br>&nbsp;&nbsp;&nbsp;&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return view('components.alert');<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>}<\/pre>\n\n\n\n<p>And, assuming the component&#8217;s <strong>Blade<\/strong> template has been defined like:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">&lt;!-- \/resources\/views\/components\/alert.blade.php --&gt;<br>&lt;div class=\"alert {{ $classForType() }}\" {{ $attributes }}&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;{{ $heading }}<br>&nbsp;&nbsp;&nbsp;&nbsp;{{ $slot }}<br>&lt;\/div&gt;<\/pre>\n\n\n\n<p>You can render the component in another <strong>Blade<\/strong> view using the component&#8217;s tag:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">&lt;x-alert type=\"error\" class=\"mb-4\"&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;x-slot name=\"heading\"&gt;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Alert content...\n&nbsp;&nbsp;&nbsp;&nbsp;&lt;\/x-slot&gt;\n Default slot content...\n &lt;\/x-alert&gt;<\/pre>\n\n\n\n<p>This is only a tiny sample of the Blade component functionality after the overhaul in Laravel 7. This sample does not show anonymous components, inline view components, or a variety of other features.&nbsp;<\/p>\n\n\n\n<div class=\"alert alert-info mb-5\"><p><strong>Note:<\/strong><br>Laravel states that the previous <code>@component<\/code> syntax for Blade components hasn&#8217;t and won&#8217;t be removed.<\/p><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"http-client\">HTTP Client<\/h2>\n\n\n\n<p>With the new update, Laravel now offers an expressive, minimal API around the Guzzle HTTP client. This API allows you to make quick ongoing HTTP requests in order to communicate with other web apps. Laravel&#8217;s Guzzle wrapper has a focus on its most common use cases, and on providing great developer experience. For example, the client makes it really easy to <code>POST<\/code> and interface with JSON data:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">use Illuminate\\Support\\Facades\\Http;<br>$response = Http::withHeaders([<br>&nbsp;&nbsp;&nbsp;&nbsp;'X-First' =&gt; 'foo'<br>&nbsp;&nbsp;&nbsp;&nbsp;'X-Second' =&gt; 'bar'<br>])-&gt;post('http:\/\/test.com\/users', [<br>&nbsp;&nbsp;&nbsp;&nbsp;'name' =&gt; 'Taylor',<br>]);<br>return $response['id'];<\/pre>\n\n\n\n<p>Additionally, the HTTP client offers amazing, ergonomic testing functionality:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Http::fake([<br>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ Stub a JSON response for GitHub endpoints...<br>&nbsp;&nbsp;&nbsp;&nbsp;'github.com\/*' =&gt; Http::response(['foo' =&gt; 'bar'], 200, ['Headers']),<br>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ Stub a string response for Google endpoints...<br>&nbsp;&nbsp;&nbsp;&nbsp;'google.com\/*' =&gt; Http::response('Hello World', 200, ['Headers']),<br>&nbsp;&nbsp;&nbsp;&nbsp;\/\/ Stub a series of responses for Facebook endpoints...<br>&nbsp;&nbsp;&nbsp;&nbsp;'facebook.com\/*' =&gt; Http::sequence()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&gt;push('Hello World', 200)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&gt;push(['foo' =&gt; 'bar'], 200)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&gt;pushStatus(404),<br>]);<\/pre>\n\n\n\n<p>If you wish to learn more about the HTTP client and its features, go check out the <a href=\"https:\/\/laravel.com\/docs\/master\/http-client\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">HTTP client documentation<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"fluent-string-operations\">Fluent String Operations<\/h2>\n\n\n\n<p>You probably are familiar with Laravel&#8217;s <code>Illuminate\\Support\\Str<\/code> class, which offers a number of string manipulation functions that can be quite helpful. Now, with, Laravel 7 you have at your disposal even more object-oriented, fluent string manipulation library, which is built on top of those functions. You have the option to create a fluent <code>Illuminate\\Support\\Stringable<\/code> object by using the <code>Str::of<\/code> method. You can then chain a variety of methods onto the object if you wish to manipulate the string:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">return (string) Str::of(' Laravel Framework 6.x ')<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&gt;trim()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&gt;replace('6.x', '7.x')<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&gt;slug();<\/pre>\n\n\n\n<p>Again, if you want access to more information on all methods available via fluent string manipulation, consult <a href=\"https:\/\/laravel.com\/docs\/master\/helpers#fluent-strings\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">the full documentation from Laravel<\/a> itself.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"improvements-in-route-model-binding\">Improvements in Route Model Binding<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"key-customization\">Key Customization<\/h3>\n\n\n\n<p>If you want to resolve Eloquent models via a column that differs from <code>id<\/code>, you can do that now. Laravel 7 allows developers the specification of columns in the route parameter definition.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">Route::get('api\/posts\/{post:slug}', function (App\\Post $post) {<br>&nbsp;&nbsp;&nbsp;&nbsp;return $post;<br>});<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"automatic-scoping\">Automatic Scoping<\/h3>\n\n\n\n<p>Sometimes you may have to bind multiple Eloquent models in a single route definition, and thus you may decide to scope the second Eloquent model to be a child of the first one. Consider the following situation, which gets a blog post by slug for a specified user:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">use App\\Post;<br>use App\\User;<br>Route::get('api\/users\/{user}\/posts\/{post:slug}', function (User $user, Post $post) {<br>&nbsp;&nbsp;&nbsp;&nbsp;return $post;<br>});<\/pre>\n\n\n\n<p>When you use a custom keyed implicit binding as a nested route parameter, Laravel 7 would automatically scope the query and retrieve the nested model by its parent. The framework does that by using conventions to guess the relationship name on the parent. So, in the particular case, the assumption would be that the User model has a relationship named <code>posts<\/code> (the plural of the route parameter name), which can be used to retrieve the <code>Post<\/code> model.<\/p>\n\n\n\n<p>For further information on route model binding, you can visit and check <a href=\"https:\/\/laravel.com\/docs\/master\/routing#route-model-binding\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">Laravel&#8217;s routing documentation<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"speed-improvements-in-route-caching\">Speed Improvements in Route Caching<\/h2>\n\n\n\n<p>Laravel 7 also includes a new method when it comes to matching compiled and cached routes, which were cached via the <code>route:cache<\/code> Artisan command. On larger applications (such with 800 or more routes), those improvements can result in <strong>doubling the speed<\/strong> for requests per second, when on <strong>a simple &#8220;Hello World&#8221; page<\/strong>. Additionally, no changes to your app are needed.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"cors-support\">CORS Support<\/h2>\n\n\n\n<p>Laravel 7 comes with first-party support for configuring Cross-Origin Resource Sharing (<strong>CORS<\/strong>) <code>OPTIONS<\/code> request responses. That&#8217;s made possible by integrating the Laravel CORS package. The default Laravel application skeleton also includes a new CORS configuration.<\/p>\n\n\n\n<p>If you need further information about the CORS support in Laravel 7.x, you can check their <a href=\"https:\/\/laravel.com\/docs\/master\/routing#cors\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">CORS documentation<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"artisan-command\">Artisan test Command<\/h2>\n\n\n\n<p>Now you can also use the test Artisan command for running your tests. The Artisan test runner offers a <strong>beautiful console UX<\/strong> and additional info in regards to the currently running test. Furthermore, the runner would automatically stop on the first test failure.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">php artisan test<\/pre>\n\n\n\n<p>All arguments that could be passed to the <code>phpunit<\/code> command can also be passed to the <strong>Artisan<\/strong> test command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">php artisan test --group=feature<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Final Thoughts<\/h2>\n\n\n\n<p>Laravel keeps getting better and better. We can only imagine what&#8217;s in store for us in the future. If you are currently using Laravel 6.x or older and want to upgrade to Laravel 7 and test all its awesome new features right away, we suggest that you create a manual backup first. <\/p>\n\n\n\n<div class=\"alert alert-info mb-5\"><p>\nIf you enjoyed this article, then you\u2019ll love <a href=\"https:\/\/www.fastcomet.com\/laravel-hosting\" target=\"_blank\" rel=\"noreferrer noopener\">FastComet\u2019s Laravel SSD Cloud<\/a> hosting platform. Experience increased power, flexibility, and control for your applications.<\/p><\/div>\n\n\n\n<p>Also, keep in mind that Laravel 7 requires <a rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\" href=\"https:\/\/www.fastcomet.com\/blog\/php-7-3-available\" target=\"_blank\">PHP 7.3<\/a> or better. Of course, we suggest that you use the latest version, which is currently <a rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\" href=\"https:\/\/www.fastcomet.com\/blog\/php-7-4-available\" target=\"_blank\">PHP 7.4<\/a>. For the complete Laravel 7.0 upgrade instructions, you may follow the official <a rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\" href=\"https:\/\/laravel.com\/docs\/7.x\/upgrade\" target=\"_blank\">Laravel Upgrade Guide<\/a>. Happy coding, everyone!<br><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Spring is almost here, but Laravel 7 couldn&#8217;t wait for it. Six months after Laravel 6, the next major release is out now and continues with its awesome new features and improvements. After version 6, Laravel is now following semver and will release a major version every six months. In this post, we will cover [&hellip;]<\/p>\n","protected":false},"author":13,"featured_media":5147,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4724],"tags":[210,78],"class_list":["post-5129","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-webdev","tag-laravel","tag-update"],"featured_image_src":"https:\/\/www.fastcomet.com\/blog\/wp-content\/uploads\/2020\/03\/laravel7.0.png","author_info":{"display_name":"Joseph","author_link":"https:\/\/www.fastcomet.com\/blog\/author\/joseph"},"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.0 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Laravel 7.0 is Here, Introducing Airlock (Sanctum) | FastComet<\/title>\n<meta name=\"description\" content=\"Laravel 7 is now released and includes Laravel Airlock (Sanctum), better routing speed, custom Eloquent casts, Blade component tags, and many more features. Check out what else is new and what&#039;s changing!\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.fastcomet.com\/blog\/laravel-7-0-is-here\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Laravel 7.0 is Here, Introducing Airlock (Sanctum) | FastComet\" \/>\n<meta property=\"og:description\" content=\"Laravel 7 is now released and includes Laravel Airlock (Sanctum), better routing speed, custom Eloquent casts, Blade component tags, and many more features. Check out what else is new and what&#039;s changing!\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.fastcomet.com\/blog\/laravel-7-0-is-here\" \/>\n<meta property=\"og:site_name\" content=\"FastComet Blog\" \/>\n<meta property=\"article:published_time\" content=\"2020-03-05T09:42:52+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2022-06-09T19:56:51+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.fastcomet.com\/blog\/wp-content\/uploads\/2020\/03\/laravel7.0.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"620\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Joseph\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Joseph\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 minutes\" \/>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Laravel 7.0 is Here, Introducing Airlock (Sanctum) | FastComet","description":"Laravel 7 is now released and includes Laravel Airlock (Sanctum), better routing speed, custom Eloquent casts, Blade component tags, and many more features. Check out what else is new and what's changing!","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.fastcomet.com\/blog\/laravel-7-0-is-here","og_locale":"en_US","og_type":"article","og_title":"Laravel 7.0 is Here, Introducing Airlock (Sanctum) | FastComet","og_description":"Laravel 7 is now released and includes Laravel Airlock (Sanctum), better routing speed, custom Eloquent casts, Blade component tags, and many more features. Check out what else is new and what's changing!","og_url":"https:\/\/www.fastcomet.com\/blog\/laravel-7-0-is-here","og_site_name":"FastComet Blog","article_published_time":"2020-03-05T09:42:52+00:00","article_modified_time":"2022-06-09T19:56:51+00:00","og_image":[{"width":1024,"height":620,"url":"https:\/\/www.fastcomet.com\/blog\/wp-content\/uploads\/2020\/03\/laravel7.0.png","type":"image\/png"}],"author":"Joseph","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Joseph","Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.fastcomet.com\/blog\/laravel-7-0-is-here#article","isPartOf":{"@id":"https:\/\/www.fastcomet.com\/blog\/laravel-7-0-is-here"},"author":{"name":"Joseph","@id":"https:\/\/www.fastcomet.com\/blog\/#\/schema\/person\/4f2c9600f49c872b8d56996ee3b95035"},"headline":"Laravel 7.0 is Here, Introducing Airlock (Sanctum)","datePublished":"2020-03-05T09:42:52+00:00","dateModified":"2022-06-09T19:56:51+00:00","mainEntityOfPage":{"@id":"https:\/\/www.fastcomet.com\/blog\/laravel-7-0-is-here"},"wordCount":1549,"commentCount":0,"image":{"@id":"https:\/\/www.fastcomet.com\/blog\/laravel-7-0-is-here#primaryimage"},"thumbnailUrl":"https:\/\/www.fastcomet.com\/blog\/wp-content\/uploads\/2020\/03\/laravel7.0.png","keywords":["Laravel","update"],"articleSection":["Development"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.fastcomet.com\/blog\/laravel-7-0-is-here#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.fastcomet.com\/blog\/laravel-7-0-is-here","url":"https:\/\/www.fastcomet.com\/blog\/laravel-7-0-is-here","name":"Laravel 7.0 is Here, Introducing Airlock (Sanctum) | FastComet","isPartOf":{"@id":"https:\/\/www.fastcomet.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.fastcomet.com\/blog\/laravel-7-0-is-here#primaryimage"},"image":{"@id":"https:\/\/www.fastcomet.com\/blog\/laravel-7-0-is-here#primaryimage"},"thumbnailUrl":"https:\/\/www.fastcomet.com\/blog\/wp-content\/uploads\/2020\/03\/laravel7.0.png","datePublished":"2020-03-05T09:42:52+00:00","dateModified":"2022-06-09T19:56:51+00:00","author":{"@id":"https:\/\/www.fastcomet.com\/blog\/#\/schema\/person\/4f2c9600f49c872b8d56996ee3b95035"},"description":"Laravel 7 is now released and includes Laravel Airlock (Sanctum), better routing speed, custom Eloquent casts, Blade component tags, and many more features. Check out what else is new and what's changing!","breadcrumb":{"@id":"https:\/\/www.fastcomet.com\/blog\/laravel-7-0-is-here#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.fastcomet.com\/blog\/laravel-7-0-is-here"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.fastcomet.com\/blog\/laravel-7-0-is-here#primaryimage","url":"https:\/\/www.fastcomet.com\/blog\/wp-content\/uploads\/2020\/03\/laravel7.0.png","contentUrl":"https:\/\/www.fastcomet.com\/blog\/wp-content\/uploads\/2020\/03\/laravel7.0.png","width":1024,"height":620},{"@type":"BreadcrumbList","@id":"https:\/\/www.fastcomet.com\/blog\/laravel-7-0-is-here#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.fastcomet.com\/blog"},{"@type":"ListItem","position":2,"name":"Laravel 7.0 is Here, Introducing Airlock (Sanctum)"}]},{"@type":"WebSite","@id":"https:\/\/www.fastcomet.com\/blog\/#website","url":"https:\/\/www.fastcomet.com\/blog\/","name":"FastComet Blog","description":"FastComet Web Hosting Blog","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.fastcomet.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.fastcomet.com\/blog\/#\/schema\/person\/4f2c9600f49c872b8d56996ee3b95035","name":"Joseph","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.fastcomet.com\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/1aa84dc2a6398ed73c957bd1de58806d12d44e2956744ed1ae9b435d57822ab7?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1aa84dc2a6398ed73c957bd1de58806d12d44e2956744ed1ae9b435d57822ab7?s=96&d=mm&r=g","caption":"Joseph"},"description":"Joseph is part of the FastComet Marketing team. With years of content writing experience behind him, it's one of his favorite activities. Joseph takes part in the SEO of the FastComet website and blog. His goal is to write comprehensive posts and guides, always aiming to help our clients with essential information. Joseph also has a thirst for knowledge and improvement, which makes the hosting environment a perfect place for him.","sameAs":["https:\/\/www.fastcomet.com\/"],"url":"https:\/\/www.fastcomet.com\/blog\/author\/joseph"}]}},"_links":{"self":[{"href":"https:\/\/www.fastcomet.com\/blog\/wp-json\/wp\/v2\/posts\/5129","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.fastcomet.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.fastcomet.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.fastcomet.com\/blog\/wp-json\/wp\/v2\/users\/13"}],"replies":[{"embeddable":true,"href":"https:\/\/www.fastcomet.com\/blog\/wp-json\/wp\/v2\/comments?post=5129"}],"version-history":[{"count":16,"href":"https:\/\/www.fastcomet.com\/blog\/wp-json\/wp\/v2\/posts\/5129\/revisions"}],"predecessor-version":[{"id":6176,"href":"https:\/\/www.fastcomet.com\/blog\/wp-json\/wp\/v2\/posts\/5129\/revisions\/6176"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.fastcomet.com\/blog\/wp-json\/wp\/v2\/media\/5147"}],"wp:attachment":[{"href":"https:\/\/www.fastcomet.com\/blog\/wp-json\/wp\/v2\/media?parent=5129"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.fastcomet.com\/blog\/wp-json\/wp\/v2\/categories?post=5129"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.fastcomet.com\/blog\/wp-json\/wp\/v2\/tags?post=5129"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}