Hey guys,
For everybody that has been upgraded to Laravel 11, cheers (me too). Laravel 11 has shipped a lot of bug fixes, improvements, and some new awesome features.
Today we'll talk about the Context - one of the new features of Laravel 11.
Laravel Context
Laravel Context is the easiest way to manage & share data in a request (or jobs, commands).
It's a layer to handle the shortage cache of your request.
Using PHP-FPM, we all know that every request is independent, thus allowing us to create static properties to store in-memory data and after the request ends, data will be flushed.
However, commands & jobs are different. They are long-lived processes, the data won't be flushed until the process ends. This makes thing harder to manage and share data.
- Same for Laravel Octane, our applications will be run in a long-lived process.
Won't be the case anymore, Laravel Context has our backs now ๐. It will ensure Context is only available during a request lifecycle (HTTP, Job, Command, and Octane's request).
Using Context
As same as how you using Cache
facade:
Context::set('seth', $seth);
Context::get('seth');
Context::forget('seth');
// and so many others
Unlike Cache
, you can store anything in-memory: string, int, Eloquent Model, Objects, etc which is really cool ๐.
All of them will be cleaned after the request ends.
Use Context in a lovely way
As we can see, whenever we need to use Context
, we have to specify the $key
If we use hardcoded string, later it will become a big mess, and hard to track usage.
Let's create a simple class to access your context.
For example, I'll have this
namespace App\Contexts; // app/Contexts folder
use App\Models\ApiKey;
use Illuminate\Support\Facades\Context;
class CurrentApiKeyContext
{
protected static string $key = 'currentApiKey';
public static function set(ApiKey $apiKey): void
{
Context::add(static::$key, $apiKey);
}
public static function get(): ApiKey
{
return Context::get(static::$key);
}
}
And when the authentication happens, I'd do:
namespace App\Http\Middleware;
use App\Contexts\CurrentApiKeyContext;
class AuthenticateApiKey
{
public function handle(Request $request, Closure $next): Response
{
$apiKey = ApiKey::findByKey($request->bearerToken());
if (!$apiKey) {
return response()->json([], 401);
}
// set key
CurrentApiKeyContext::set($apiKey);
return $next($apiKey);
}
}
After that, whenever I need to access the currentApiKey
, I'd do:
use App\Contexts\CurrentApiKeyContext;
CurrentApiKeyContext::get(); // ApiKey instance
The PROs
Your
$key
will be defined once and maintained inside a classYour data will be strictly-typed & IDE-friendly
- No more
/** @var ... */
pain, I feel that
- No more
Easy to write unit test cases
The CONs
- You have a new layer to manage
Conclusion
Everything is a trade-off in tech, and since the PROs are better, why don't we go that? ๐
Let's just not make it work, let's make it better & easier to manage in a later stage โค๏ธ.
Cheers, and happy Friday!