NotionCommotion Posted January 12, 2019 Share Posted January 12, 2019 Where should the validation take place? Several options include: In the Slim closure. i.e. $app->get('/', function(){/* validate before calling service */}) In the service. In the mapper. In the entity domain. I can easily create the standalone Validator class to validate scenarios such as whether a property is provided and whether it meets certain rules, however, other scenarios such as whether a record exists is closely linked to the mapper. Also, the entity does a good job confirming that the write properties are being provided. How important is it to locate validation at one place? Thanks <?php use \Psr\Http\Message\ServerRequestInterface as Request; use \Psr\Http\Message\ResponseInterface as Response; $c = new \Slim\Container(); $c['validator'] = function ($c) {}; $c['pdo'] = function ($c) {}; $c['resourceService'] = function ($c) { return new Resource\ResourceService( new Resource\ResourceMapper( $c['pdo'], $c['validator'] ), $c['validator'] ); }; $c['resourceResponder'] = function ($c) {}; $app = new \Slim\App($c); $app->get('/someResource', function (Request $request, Response $response) { return $this->resourceResponder->index($response, $this->resourceService->index($request->getQueryParams())); }); $app->get('/someResource/{id:[0-9]+}', function (Request $request, Response $response, $args) { return $this->resourceResponder->detail($response, $this->resourceService->read($args['id'])); }); $app->post('/someResource', function (Request $request, Response $response, $args) { return $this->resourceResponder->create($response, $this->resourceService->create($request->getParsedBody())); }); $app->put('/someResource/{id:[0-9]+}', function (Request $request, Response $response, $args) { return $this->resourceResponder->update($response, $this->resourceService->update($args['id'], $request->getParsedBody())); }); $app->delete('/someResource/{id:[0-9]+}', function (Request $request, Response $response, $args) { return $this->resourceResponder->delete($response, $this->resourceService->delete($args['id'])); }); $app->run(); class ResourceService { protected $mapper, $validator; public function __construct(Mapper $mapper, Validator $validator) { $this->mapper = $mapper; $this->validator = $validator; } public function index(array $params=[]):array { $index = $this->mapper->index($params); return $index; } public function read(int $id):Entity { $entity = $this->mapper->read($id); return $entity; } public function create(array $params):int { $entity=$this->mapper->create($params); $id=$this->mapper->save($entity); return $id; } public function update(int $id, array $params):int { $this->update->update($id, $params); return $id; } public function delete(int $id):null { $this->mapper->delete($id); } } class ResourceMapper { protected $pdo, $validator; public function __construct(\Pdo $pdo, Validator $validator) { $this->pdo = $pdo; $this->validator = $validator; } public function index(array $params=[]):array { //query DB and return an array of Resources } public function read(int $id):Entity { if(!$params=$this->queryDatabase($id)) { throw new \Exception("ID $id does not exist"); } return new Resource($params); } public function create(array $params):int { //Or should the service create the entity? return new ResourceEntity($params); } public function save(Entity $entity):int { //Save the data. What if a duplicate error? return $this->pdo->lastInsertId(); } public function update(int $id, array $params):null { //update database. What if id doesn't exist? } public function delete(int $id):null { //Delete from DB. What if id doesn't exist or foreign key constraint? } } class ResourceEntity { public function __construct(array $params, Validator $validator) { //As applicable } } Quote Link to comment Share on other sites More sharing options...
requinix Posted January 14, 2019 Share Posted January 14, 2019 On 1/12/2019 at 9:53 AM, NotionCommotion said: How important is it to locate validation at one place? Less important than separation of concerns and the single responsibility principle. You can always propagate errors up through the stack. Exceptions are good for that, and with them you can wrap low-level exceptions as they come up. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.