[REQ][Slim4] Request Validation
Created by: ybelenko
Is your feature request related to a problem? Please describe.
I thought about perfect API implementation a lot and I think it should contain 5 steps mock -> auth -> validation -> business logic -> process and exactly in that order.
-
Mockstep returns example response when mock feature is enabled. Skipped otherwise. Feature discussion #3545 (closed) -
Auth(authentication) step checks authorization. Returns401 Unauthorizedwhen token/credentials are invalid. -
Validationstep should validate all request parameters. Just basic validation, data types comparison, etc. Returns400 Bad Requeston fail. -
Business Logicstep is part of validation but checks if request cannot be processed by other reasons(username already exists, premium account required, etc.). Returns400 Bad Requestwith verbose error description on fail. -
Processstep executes request and returns final response with2xxhttp status code. Most of time this step related to database/storage quering.
Current issue related to third step Validation.
Describe the solution you'd like
PHP Slim4 server should contain validation middleware. Something like that:
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface as RequestHandler;
use Slim\Psr7\Response;
class ValidationMiddleware implements MiddlewareInterface
{
public function process(Request $request, RequestHandler $handler): Response
{
if ($this->validate($request) === true) {
// everything fine, continue
return $handler->handle($request);
}
// request is malformed or invalid, return client error response
$response = new Response();
// just an example of client error response body
$response->getBody()->write(json_encode([
'error' => 'invalid request',
'error_description' => 'Request is malformed or invalid.',
]));
// common practice to return 4xx status response when client request cannot be prcocessed
// most of time you'll see '400 Bad Request' or '422 Unprocessable Entity'
return $response->withStatus(400);
}
public function validate(Request $request): bool
{
// let's imagine that accordingly to spec current request
// must contain 'username' query param as string less or equal 50 chars
$params = $request->getQueryParams();
if (is_string($params['username']) && mb_strlen($params['username']) <= 50) {
return true;
}
return false;
}
}
Additional context
I'm working on that feature. This issue created to describe how Slim4 server will be enhanced, kind of roadmap.
cc @jebentier, @dkarlovi, @mandrean, @jfastnacht, @ackintosh, @renepardon