Skip to main content

Overview

The InjectRequestParams middleware allows you to inject static or dynamic parameters directly into the request from route definitions. It supports intelligent type casting including booleans, nulls, numbers, JSON, and base64-encoded payloads.

Basic Usage

Route::post('/tasks', [TaskController::class, 'store'])
    ->middleware('inject:scenario=assign,mode=REVOKE,dry_run=true');
The above injects three parameters:
  • scenario = "assign" (string)
  • mode = "REVOKE" (string)
  • dry_run = true (boolean)

Parameters

The middleware accepts variable arguments in the format key=value or key:value:
...pairs
string
Key-value pairs to inject. Supports both = and : as separators.

Options

Leading parameters modify the injection behavior:
ns
string
Namespace prefix for all injected keys. Example: ns=_meta injects keys as _meta.key
force
boolean
default:"false"
When true, overwrites existing request values. By default, only sets values if not already present.

Value Casting

The middleware automatically casts string values to appropriate PHP types:

Boolean Values

// Route
->middleware('inject:active=true,verified=false')

// Result
$request->get('active');   // true (boolean)
$request->get('verified'); // false (boolean)

Null Values

// Route
->middleware('inject:deleted_at=null')

// Result
$request->get('deleted_at'); // null

Numeric Values

// Route
->middleware('inject:count=42,price=19.99')

// Result
$request->get('count'); // 42 (int)
$request->get('price'); // 19.99 (float)

JSON Objects and Arrays

Prefix with json: to decode JSON:
// Route
->middleware('inject:config=json:{"theme":"dark","lang":"en"}')

// Result
$request->get('config'); // ['theme' => 'dark', 'lang' => 'en']
// Array example
->middleware('inject:roles=json:["admin","editor"]')

// Result
$request->get('roles'); // ['admin', 'editor']

Base64-Encoded Values

Prefix with b64: to decode base64. If the decoded content looks like JSON, it’s automatically decoded:
// Route (base64 of '{"id":123}')
->middleware('inject:data=b64:eyJpZCI6MTIzfQ==')

// Result
$request->get('data'); // ['id' => 123]

Plain Strings

Any value that doesn’t match special patterns is kept as a string:
// Route
->middleware('inject:name=John Doe,status=pending')

// Result
$request->get('name');   // "John Doe" (string)
$request->get('status'); // "pending" (string)

Advanced Usage

Namespace Prefixing

Group injected parameters under a namespace:
Route::post('/process', [ProcessController::class, 'handle'])
    ->middleware('inject:ns=_meta,version=2,author=system');

// Controller
$request->get('_meta.version'); // 2
$request->get('_meta.author');  // "system"

Force Overwrite

Overwrite existing request values:
Route::post('/tasks', [TaskController::class, 'store'])
    ->middleware('inject:force,status=pending');

// Even if client sends { "status": "active" },
// it will be overwritten to "pending"

Combined Options

Route::post('/admin/users', [AdminUserController::class, 'store'])
    ->middleware('inject:ns=_meta,force,created_by=admin,timestamp=1234567890');

// Result
$request->get('_meta.created_by');  // "admin"
$request->get('_meta.timestamp');   // 1234567890

Use Cases

Scenario-Based Processing

// Assign route
Route::post('/users/{user}/roles', [RoleController::class, 'process'])
    ->middleware('inject:scenario=assign');

// Revoke route
Route::delete('/users/{user}/roles', [RoleController::class, 'process'])
    ->middleware('inject:scenario=revoke');

// Controller
public function process(Request $request)
{
    $scenario = $request->get('scenario'); // 'assign' or 'revoke'
    // ...
}

Audit Metadata

Route::middleware('inject:ns=_audit,source=api,version=2')
    ->group(function () {
        Route::post('/articles', [ArticleController::class, 'store']);
        Route::put('/articles/{id}', [ArticleController::class, 'update']);
    });

// Access in controller or observers
$source = $request->get('_audit.source');   // "api"
$version = $request->get('_audit.version'); // 2

Feature Flags

Route::post('/payments/process', [PaymentController::class, 'process'])
    ->middleware('inject:use_new_gateway=true,retry_on_failure=true');

Default Values

// Set defaults that can be overridden by the client
Route::post('/reports', [ReportController::class, 'generate'])
    ->middleware('inject:format=pdf,include_summary=true');

// With force, make values immutable
Route::post('/public/feedback', [FeedbackController::class, 'store'])
    ->middleware('inject:force,source=public,verified=false');

Request Attributes

Injected values are also stored as request attributes (not just input), making them accessible via:
// Both work:
$request->get('key');           // From input
$request->attributes->get('key'); // From attributes

Type Casting Reference

InputOutputType
truetrueboolean
falsefalseboolean
nullnullnull
4242integer
19.9919.99float
json:{...}[...]array
json:[...][...]array
b64:...decoded string or arraymixed
hello"hello"string

Examples

Complex JSON Injection

Route::post('/workflows', [WorkflowController::class, 'execute'])
    ->middleware(
        'inject:config=json:{"timeout":30,"retry":3,"notify":true}'
    );

// Controller
$config = $request->get('config');
// ['timeout' => 30, 'retry' => 3, 'notify' => true]

Multiple Middleware Instances

Route::post('/process', [ProcessController::class, 'handle'])
    ->middleware([
        'inject:ns=_meta,version=2,source=api',
        'inject:force,dry_run=false',
    ]);

See Also

Build docs developers (and LLMs) love