Skip to content

Commit 5fe2d53

Browse files
committed
add usage for Laravel Middleware
1 parent a4f39c6 commit 5fe2d53

File tree

1 file changed

+124
-0
lines changed

1 file changed

+124
-0
lines changed

README.md

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,3 +282,127 @@ class GetHelloTest extends TestCase
282282
}
283283
}
284284
```
285+
286+
## Usage for Laravel Middleware
287+
288+
### 1. create a Middleware class
289+
290+
```php
291+
<?php
292+
293+
declare(strict_types=1);
294+
295+
namespace App\Http\Middleware;
296+
297+
use Closure;
298+
use Illuminate\Contracts\Routing\ResponseFactory;
299+
use N1215\OpenApiValidation\HttpFoundation\Validators;
300+
use N1215\OpenApiValidation\OperationAddress;
301+
use N1215\OpenApiValidation\RequestValidationFailed;
302+
use N1215\OpenApiValidation\ResponseValidationFailed;
303+
use Symfony\Component\HttpFoundation\Response;
304+
305+
class ValidateWithOpenApi
306+
{
307+
private string $basePath = '/';
308+
309+
private Validators $validators;
310+
311+
private ResponseFactory $responseFactory;
312+
313+
public function __construct(Validators $validators, ResponseFactory $responseFactory)
314+
{
315+
$this->validators = $validators;
316+
$this->responseFactory = $responseFactory;
317+
}
318+
319+
/**
320+
* Handle an incoming request.
321+
*
322+
* @param \Illuminate\Http\Request $request
323+
* @param \Closure $next
324+
* @return mixed
325+
*/
326+
public function handle($request, Closure $next)
327+
{
328+
try {
329+
$this->validators->getRequestValidator()->validate($request);
330+
} catch (RequestValidationFailed $e) {
331+
return $this->responseFactory->json(
332+
[
333+
'message' => $e->getMessage(),
334+
],
335+
Response::HTTP_INTERNAL_SERVER_ERROR
336+
);
337+
}
338+
339+
$response = $next($request);
340+
assert($response instanceof Response);
341+
342+
$pattern = '/^' . preg_quote($this->basePath, '/') . '/';
343+
$relativePath = '/' . preg_replace($pattern, '', $request->getPathInfo());
344+
try {
345+
$this->validators->getResponseValidator()->validate(
346+
new OperationAddress(
347+
$relativePath,
348+
$request->method()
349+
),
350+
$response
351+
);
352+
} catch (ResponseValidationFailed $e) {
353+
return $this->responseFactory->json(
354+
[
355+
'message' => $e->getMessage(),
356+
],
357+
Response::HTTP_INTERNAL_SERVER_ERROR
358+
);
359+
}
360+
361+
return $response;
362+
}
363+
}
364+
```
365+
366+
### 2. register to the service container
367+
368+
```php
369+
<?php
370+
371+
declare(strict_types=1);
372+
373+
namespace App\Providers;
374+
375+
use App\Http\Middleware\ValidateWithOpenApi;
376+
use Illuminate\Support\Facades\Cache;
377+
use Illuminate\Support\ServiceProvider;
378+
use N1215\OpenApiValidation\HttpFoundation\ValidatorBuilder;
379+
use N1215\OpenApiValidation\HttpFoundation\Validators;
380+
use Nyholm\Psr7\Factory\Psr17Factory;
381+
use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
382+
383+
class AppServiceProvider extends ServiceProvider
384+
{
385+
/**
386+
* Register any application services.
387+
*
388+
* @return void
389+
*/
390+
public function register()
391+
{
392+
$this->app->singleton(Validators::class, function () {
393+
$psr17Factory = new Psr17Factory();
394+
$httpMessageFactory = new PsrHttpFactory(
395+
$psr17Factory,
396+
$psr17Factory,
397+
$psr17Factory,
398+
$psr17Factory
399+
);
400+
return (new ValidatorBuilder($httpMessageFactory))
401+
->fromYamlFile(__DIR__ . '/openapi.yaml')
402+
->setSimpleCache(Cache::store(), 3600)
403+
->getValidators();
404+
});
405+
$this->app->singleton(ValidateWithOpenApi::class);
406+
}
407+
}
408+
```

0 commit comments

Comments
 (0)