Validate JSON Request with Respect/Validation

336 Views Asked by At

I have a JSON request which exactly follow the rules, but the result keeps failing. Let's say I have a request like this:

{
"name"  :   "Angela White",
"dateOfBirth" : "01/01/98"
}

and this is my controller:

class RegisterController extends Controller {
    
    public function register($request, $response) {
        $parsedBody = $request->getParsedBody();
        
        $name = trim($parsedBody['name']);
        $dateOfBirth = $parsedBody['dateOfBirth'];
        
        $customer = new Customer();
        $customer->setName($name);
        $customer->setDateOfBirth($dateOfBirth);
        
        $rules = $customer->customerValidator();

        $data = array(
            'name'  => $name,
            'dateOfBirth'  => $dateOfBirth,
        );

        
        foreach($data as $key => $val) {
            try{
                $rules->check($val);
            } catch(\InvalidArgumentException $e) {
                $errors = $e->getMessage();
                return $response->withJson($errors, 401);
                
            }
        }
    }
}

This is class to validate the data:

class Customer {
    private $name;
    private $dateOfBirth;
    
    public function setName($input) {
        $this->name = $input;
    }

    public function getName() {
        return $this->name;
    }

    public function setDateOfBirth($input) {
        $this->dateOfBirth = $input;
    }

    public function getDateOfBirth() {
        return $this->dateOfBirth;
    }

    
    public function customerValidator() {
        
        return v::attribute($this->getName(), v::stringType()->length(2, null)->setName('Name'))
            ->attribute('dateOfBirth', v::notEmpty()->date('d/m/y')->setName('Date of birth'));

    }


}

And as the result I got this:

{
    "API_Response": {
        "Status": {
            "Message": "Attribute Name must be present",
            "_ErrorCode": 401,
            "_TimeStamp": 1647247097
        }
    }
}

I expect the result is success but why is the message still "Attribute Name must be present" ? Does anyone can help me, what have I missed? Thanks!

1

There are 1 best solutions below

1
On

There are different issues.

1. Usage of the attribute validator

The one that's inside the customerValidator function. Here you are using the attribute rule that accepts the name of the attribute and not its value. Replacing $this->getName() with 'name' should be enough:

class Customer {
  private $name;
  private $dateOfBirth;

  public function setName($input) {
    $this->name = $input;
  }

  public function getName() {
    return $this->name;
  }

  public function setDateOfBirth($input) {
    $this->dateOfBirth = $input;
  }

  public function getDateOfBirth() {
    return $this->dateOfBirth;
  }

  public function customerValidator() {
    return v::attribute('name', v::stringType()->length(2, null)->setName('Name'))
        ->attribute('dateOfBirth', v::notEmpty()->date('d/m/y')->setName('Date of birth'));

  }

}

2. Validation check in the controller

You already have the object with all the properties set, so it's better to validate it, instead of iterating over all the keys you defined.

class RegisterController extends Controller {
    
    public function register($request, $response) {
        $parsedBody = $request->getParsedBody();
        
        $name = trim($parsedBody['name']);
        $dateOfBirth = $parsedBody['dateOfBirth'];
        
        $customer = new Customer();
        $customer->setName($name);
        $customer->setDateOfBirth($dateOfBirth);
        
        $rules = $customer->customerValidator();

        $data = array(
            'name'  => $name,
            'dateOfBirth'  => $dateOfBirth,
        );

        try{
            $rules->check($customer);
        } catch(\InvalidArgumentException $e) {
            $errors = $e->getMessage();
            return $response->withJson($errors, 401);
        }
    }
}