Jump to content

Where should validation be performed?


NotionCommotion

Recommended Posts

Where should the validation take place?  Several options include:

  1. In the Slim closure.  i.e. $app->get('/', function(){/* validate before calling service */})
  2. In the service.
  3. In the mapper.
  4. 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
    }
}

 

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.