├── .gitignore ├── .travis.yml ├── CODEOWNERS ├── LICENSE ├── README.md ├── composer.json ├── phpunit.xml ├── src └── RequestId.php └── tests └── RequestIdTest.php /.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | composer.lock -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | php: 3 | - '7.0' 4 | - '7.1' 5 | install: 6 | - composer install 7 | script: vendor/bin/phpunit 8 | -------------------------------------------------------------------------------- /CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @joskfg 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019 Softonic International S.A. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # softonic/laravel-middleware-request-id 2 | [![Build Status](https://travis-ci.org/softonic/laravel-middleware-request-id.svg?branch=master)](https://travis-ci.org/softonic/laravel-middleware-request-id) 3 | 4 | ## Install 5 | 6 | ```bash 7 | $ composer require softonic/laravel-middleware-request-id 8 | ``` 9 | 10 | ## Usage 11 | 12 | ### For all routes or a specific group 13 | 14 | Add `Softonic\Laravel\Middleware\RequestId::class` in `App\Http\Kernel`. 15 | 16 | For all routes: 17 | ```php 18 | protected $middleware = [ 19 | \Softonic\Laravel\Middleware\RequestId::class, 20 | .... 21 | ] 22 | ``` 23 | 24 | Specific group: 25 | ```php 26 | // Example for WEB group 27 | protected $middlewareGroups = [ 28 | 'web' => [ 29 | \Softonic\Laravel\Middleware\RequestId::class, 30 | ... 31 | ], 32 | 33 | 'api' => [ 34 | ... 35 | ], 36 | ]; 37 | ``` 38 | 39 | ### For a specific route 40 | 41 | Register the middleware as a route middleware in `App\Http\Kernel`. 42 | ```php 43 | protected $routeMiddleware = [ 44 | ... 45 | 'request-id' => Softonic\Laravel\Middleware\RequestId::class, 46 | ]; 47 | ``` 48 | 49 | then, use it in your routes file, for example in `routes\web.php` 50 | ```php 51 | Route::get('route', function() {})->middleware('request-id'); 52 | ``` 53 | 54 | ### Extra 55 | 56 | If you need to have the X-Request-Id ASAP, you can modify `\App\Providers\AppServiceProvider::boot` adding `$_SERVER['HTTP_X_REQUEST_ID'] ??= \Ramsey\Uuid\Uuid::uuid4()->toString();`. 57 | This is going to allow you to use the X-Request-ID in the framework booting to for example customize monolog or in console executions. 58 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "softonic/laravel-middleware-request-id", 3 | "description": "Middleware for Laravel Framework to add the X-Request-ID header in the requests and responses.", 4 | "authors": [ 5 | { 6 | "name": "Jose Manuel Cardona", 7 | "email": "josemanuel.cardona@softonic.com" 8 | } 9 | ], 10 | "keywords": [ 11 | "laravel", 12 | "middleware", 13 | "tracking" 14 | ], 15 | "license": "Apache-2.0", 16 | "type": "library", 17 | "require": { 18 | "php": ">=7.4", 19 | "illuminate/http": ">7.0", 20 | "ramsey/uuid": "^4.0.0" 21 | }, 22 | "require-dev": { 23 | "phpunit/phpunit": "^9.0" 24 | }, 25 | "autoload": { 26 | "psr-4": { 27 | "Softonic\\Laravel\\Middleware\\": "src/" 28 | } 29 | }, 30 | "autoload-dev": { 31 | "psr-4": { 32 | "Softonic\\Laravel\\Middleware\\": "tests/" 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | ./tests 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/RequestId.php: -------------------------------------------------------------------------------- 1 | headers->get('X-Request-ID'); 27 | 28 | if (is_null($uuid)) { 29 | $uuid = Uuid::uuid4()->toString(); 30 | 31 | $request->headers->set('X-Request-ID', $uuid); 32 | } 33 | 34 | $_SERVER['HTTP_X_REQUEST_ID'] = $uuid; 35 | 36 | $response = $next($request); 37 | 38 | $response->headers->set('X-Request-ID', $uuid); 39 | 40 | return $response; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /tests/RequestIdTest.php: -------------------------------------------------------------------------------- 1 | assertThat( 20 | method_exists($request_id, 'handle'), 21 | $this->isTrue(), 22 | 'A middleware must have a handle method.' 23 | ); 24 | } 25 | 26 | public function testRequestIdShouldBeFilledIfDoesNotExistInRequestAndResponse() 27 | { 28 | $request = new Request(); 29 | $response = new Response(); 30 | 31 | $closure = function (Request $request) use ($response) { 32 | $this->assertNotEmpty($request->header('X-Request-ID')); 33 | 34 | return $response; 35 | }; 36 | 37 | $request_id = new RequestId(); 38 | $response = $request_id->handle($request, $closure); 39 | 40 | $this->assertNotEmpty( 41 | $request->header('X-Request-ID'), 42 | 'The X-Request-ID header must exists.' 43 | ); 44 | $this->assertEquals( 45 | $response->headers->get('X-Request-ID'), 46 | $request->header('X-Request-ID'), 47 | 'The same X-Request-ID must be set in request and response.' 48 | ); 49 | $this->assertEquals( 50 | $response->headers->get('X-Request-ID'), 51 | $_SERVER['HTTP_X_REQUEST_ID'], 52 | 'The same X-Request-ID must be set in server globals.' 53 | ); 54 | } 55 | 56 | public function testPropagateRequestIdToResponseIfProvidedInRequest() 57 | { 58 | $request = new Request(); 59 | $request->headers->set('X-Request-ID', '09226165-364a-461a-bf5c-e859d70d907e'); 60 | $response = new Response(); 61 | 62 | $closure = function (Request $request) use ($response) { 63 | $this->assertEquals( 64 | '09226165-364a-461a-bf5c-e859d70d907e', 65 | $request->header('X-Request-ID'), 66 | 'The Request header must not be modified.' 67 | ); 68 | 69 | return $response; 70 | }; 71 | 72 | $request_id = new RequestId(); 73 | $response = $request_id->handle($request, $closure); 74 | 75 | $this->assertEquals( 76 | '09226165-364a-461a-bf5c-e859d70d907e', 77 | $response->headers->get('X-Request-ID'), 78 | 'The request X-Request-ID header must be set in the response.' 79 | ); 80 | $this->assertEquals( 81 | '09226165-364a-461a-bf5c-e859d70d907e', 82 | $_SERVER['HTTP_X_REQUEST_ID'], 83 | 'The same X-Request-ID must be set in server globals.' 84 | ); 85 | } 86 | } 87 | --------------------------------------------------------------------------------