# Use Laravel Context in a lovely & maintainable way 🥰

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**](https://laravel.com/docs/11.x/context#main-content) 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:

```php
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

```php
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:

```php
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:

```php
use App\Contexts\CurrentApiKeyContext;

CurrentApiKeyContext::get(); // ApiKey instance
```

### The PROs

* Your `$key` will be defined once and maintained inside a class
    
* Your data will be strictly-typed & IDE-friendly
    
    * No more `/** @var ... */` pain, I feel that
        
* 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!
