SlideShare a Scribd company logo
Data validation models
Marcin Czarnecki - Tech Lead
What is validation?
<form method="post">
<input name="email" type="email">
<input name="username" type="text" minlength="3">
<input name="password" type="password">
<input name="submit" type="submit" value="Register">
</form>
<?php
require(‘user_functions.php’);
if (!empty($_POST['email'])) {
if (!empty($_POST['password'])) {
if (!empty($_POST['username'])) {
save_user($_POST);
echo "User created";
exit();
}
die("empty username");
}
die("empty password");
}
die("empty email");
<?php
use SymfonyComponentValidatorConstraints as Assert;
class User
{
/**
* @AssertNotBlank
* @AssertString
* @AssertEmail
*/
public $email
/**
* @AssertNotBlank
* @AssertLength(min=“3”)
*/
public $username;
}
<?php
use AssertAssert;
class User
{
private string $username;
private string $email;
/* @throw InvalidArgumentException */
public function __construct(string $username, string $email)
{
Assert::stringNotEmpty($username);
Assert::minLength($username, 3);
Assert::stringNotEmpty($email);
Assert::email($email);
$this->username = $username;
$this->email = $email;
}
}
create table users
(
id bigint not null primary key auto_increment,
email varchar(100) not null,
username varchar(100) not null,
constraint email_unique unique (email),
constraint username_unique unique (username)
)
Two types of data validation
Optional section title
Syntactic
Checks if data has the proper
data type and format
2020-02-30
Invalid date
2030-02-03
Looks like a valid date!
Semantic
Checks if data makes sense in
our use case
2030-02-03
Seems to be invalid DoB
1903-01-02
??? ??? ??? ??? ??? ???
Syntactic validation
{
"email": “mczarnecki@example.com" // valid
}
{
"email": “mczarnecki@example.com" // valid
}
{
"email": 12345679 // invalid - wrong data type
}
{
"email": “mczarnecki@example.com" // valid
}
{
"email": 12345679 // invalid - wrong data type
}
{
"email": “mczarnecki@example" // invalid - wrong domain
}
{
"email": “mczarnecki@example.com" // valid
}
{
"email": 12345679 // invalid - wrong data type
}
{
"email": “mczarnecki@example" // invalid - wrong domain
}
{
"email": “” // invalid - empty string
}
{
"email": “mczarnecki@example.com" // valid
}
{
"email": 12345679 // invalid - wrong data type
}
{
"email": “mczarnecki@example" // invalid - wrong domain
}
{
"email": “” // invalid - empty string
}
{
"email": “mczarnecki+spam@example.com" // valid
}
Is it so simple?
filter_var($email, FILTER_VALIDATE_EMAIL) vs RFC5321
mczarnecki(comment)@example.com
уникум@из.рф
"this is v@lid!"@example.com
"()<>[]:,;@"!#$%&'*+-/=?^_`{}| ~.a”@example.org
" “@example.org
localpart.ending.with.dot.@example.com
When should I be more careful about syntax
validation?
➔ Integrations with external APIs (for example oAuth)
➔ It is a core of our application
Optional section title
Usually it will be just an edge case
Semantic validation
I got mczarnecki@example.com as input, but such
user already exists. Is it valid?
Optional section title
I got mczarnecki@example.com as input, but such
user already exists. Is it valid?
➔ Register user context
● Definitely NO!
Optional section title
I got mczarnecki@example.com as input, but such
user already exists. Is it valid?
➔ Register user context
● Definitely NO!
➔ Login user context
● Yes, it is valid
Optional section title
I got mczarnecki@example.com as input, but such
user already exists. Is it valid?
➔ Register user context
● Definitely NO!
➔ Login user context
● Yes, it is valid
➔ Search for friend
● No such validation rule.
Optional section title
I got mczarnecki@example.com as input, but such
user already exists. Is it valid?
➔ Register user context
● Definitely NO!
➔ Login user context
● Yes, it is valid
➔ Search for friend
● No such validation rule.
➔ Send order confirmation email
● Yes, it is required to exist in database
Optional section title
How to implemented it
Syntactic validation
As soon as possible
Before deserialisation or just after it.
Optional section title
Deferred validation
<?php
use SymfonyComponentValidatorConstraints as Assert;
class RegisterUserRequest {
/**
* @AssertNotBlank
* @AssertString
*/
public $email
/**
* @AssertNotBlank
* @AssertLength(min=“3”)
*/
public $username;
}
Make sure that you will
always operate on valid object
Use Argument Resolver and kernel.exception listener to handle
invalid requests
Optional section title
<?php
use SymfonyComponentValidatorConstraints as Assert;
class RegisterUserRequestResolver implements ArgumentValueResolverInterface
{
private SerializerInterface $serializer;
private ValidatorInterface $validator;
public function __construct(
SerializerInterface $serializer,
ValidatorInterface $validator
)
{
$this->serializer = $serializer;
$this->validator = $validator;
}
<?php
class RegisterUserRequestResolver implements ArgumentValueResolverInterface
{
public function supports(Request $request, ArgumentMetadata $argument)
{
return RegisterUserRequest::class === $argument->getType();
}
public function resolve(Request $request, ArgumentMetadata $argument)
{
$dto = $this->serializer->deserialize($request->getContent(),
RegisterUserRequest::class, 'json');
$errors = $this->validator->validate($dto);
if($errors->count()){
throw new Exception((string)$errors);
}
yield $dto;
}
}
<?php
class ExceptionListener
{
public function onKernelException(ExceptionEvent $event)
{
$exception = $event->getThrowable();
$response = new Response();
$response->setContent($exception->getMessage());
$response->setStatusCode(Response::HTTP_BAD_REQUEST);
$event->setResponse($response);
}
}
<?php
class UserController
{
public function index(RegisterUserRequest $request)
{
$this->usersService->createUser(
$request->email,
$request->username,
);
return new Response('', Response::HTTP_CREATED);
}
}
Semantic validation
Domain model should be
always valid
To keep your code DRY most of the semantic validation should take
place in the application / domain layer.
Optional section title
<?php
class UserController
{
public function index(RegisterUserRequest $request)
{
$this->usersService->createUser(
$request->email,
$request->username,
);
return new Response('', Response::HTTP_CREATED);
}
}
<?php
class UserController
{
public function index(RegisterUserRequest $request)
{
$this->usersService->createUser(
new Username($request->username),
new Email($request->email),
);
return new Response('', Response::HTTP_CREATED);
}
}
<?php
use WebmozartAssertAssert;
class Email
{
private string $email;
public function __construct(string $email)
{
Assert::email($email);
$this->email = $email;
}
}
<?php
class UserService
{
public function createUser(Username $username, Email $email)
{
if($this->usersRepository->findByEmail($email)){
throw new UserAlreadyExists();
}
if($this->usersRepository->findByUsername($username)){
throw new UserAlreadyExists();
}
$this->usersRepository->add(new User(
$email,
$username
));
}
<?php
use WebmozartAssertAssert;
class User
{
private string $email;
public function __construct(string $email)
{
Assert::email($email);
$this->email = $email;
}
}
Librairies and performance
+-------------------------+----------+----------+
| benchmark | mean | mem_peak |
+-------------------------+----------+----------+
| BeberleiAssertBench | 4.490μs | 1.237mb |
| WebmozartValidatorBench | 4.376μs | 1.200mb |
| BeberleiLazyAssertBench | 20.786μs | 1.295mb |
| Symfony4ValidatorBench | 25.435μs | 1.384mb |
| Symfony5ValidatorBench | 30.400μs | 1.441mb |
| Symfony6ValidatorBench | 32.061μs | 1.366mb |
| LaravelBench | 15.470μs | 2.339mb |
| LaminasBench | 97.789μs | 1.296mb |
+-------------------------+----------+----------+
+-------------------------+----------+----------+
| benchmark | mean | mem_peak |
+-------------------------+----------+----------+
| BeberleiAssertBench | 4.490μs | 1.237mb |
| WebmozartValidatorBench | 4.376μs | 1.200mb |
| BeberleiLazyAssertBench | 20.786μs | 1.295mb |
| Symfony4ValidatorBench | 25.435μs | 1.384mb |
| Symfony5ValidatorBench | 30.400μs | 1.441mb |
| Symfony6ValidatorBench | 32.061μs | 1.366mb |
| LaravelBench | 15.470μs | 2.339mb |
| LaminasBench | 97.789μs | 1.296mb |
+-------------------------+----------+----------+
+-------------------------+----------+----------+
| benchmark | mean | mem_peak |
+-------------------------+----------+----------+
| BeberleiAssertBench | 4.490μs | 1.237mb |
| WebmozartValidatorBench | 4.376μs | 1.200mb |
| BeberleiLazyAssertBench | 20.786μs | 1.295mb |
| Symfony4ValidatorBench | 25.435μs | 1.384mb |
| Symfony5ValidatorBench | 30.400μs | 1.441mb |
| Symfony6ValidatorBench | 32.061μs | 1.366mb |
| LaravelBench | 15.470μs | 2.339mb |
| LaminasBench | 97.789μs | 1.296mb |
+-------------------------+----------+----------+
+-------------------------+----------+----------+
| benchmark | mean | mem_peak |
+-------------------------+----------+----------+
| BeberleiAssertBench | 4.490μs | 1.237mb |
| WebmozartValidatorBench | 4.376μs | 1.200mb |
| BeberleiLazyAssertBench | 20.786μs | 1.295mb |
| Symfony4ValidatorBench | 25.435μs | 1.384mb |
| Symfony5ValidatorBench | 30.400μs | 1.441mb |
| Symfony6ValidatorBench | 32.061μs | 1.366mb |
| LaravelBench | 15.470μs | 2.339mb |
| LaminasBench | 97.789μs | 1.296mb |
+-------------------------+----------+----------+
Try it out
github.com/scyzoryck/php-validators-benchmark
Thanks to phpbench/phpbench
Take away
Take away
➔Syntactic validation should be done as soon as possible
➔Semantic validation should be implemented in the
application / domain level
➔We should avoid of operating on incorrect objects
➔Always validate your input :)
Optional section title
Thank you
twitter.com/scyzoryck


github.com/scyzoryck

More Related Content

What's hot

New in php 7
New in php 7New in php 7
New in php 7
Vic Metcalfe
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using Codeception
Jeroen van Dijk
 
Zend Certification Preparation Tutorial
Zend Certification Preparation TutorialZend Certification Preparation Tutorial
Zend Certification Preparation Tutorial
Lorna Mitchell
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
Konstantin Kudryashov
 
PhpSpec 2.0 ilustrated by examples
PhpSpec 2.0 ilustrated by examplesPhpSpec 2.0 ilustrated by examples
PhpSpec 2.0 ilustrated by examples
Marcello Duarte
 
Php functions
Php functionsPhp functions
Php functions
JIGAR MAKHIJA
 
Rich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationRich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 Application
Kirill Chebunin
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il cliente
Leonardo Proietti
 
The IoC Hydra
The IoC HydraThe IoC Hydra
The IoC Hydra
Kacper Gunia
 
Php pattern matching
Php pattern matchingPhp pattern matching
Php pattern matching
JIGAR MAKHIJA
 
Speed up your developments with Symfony2
Speed up your developments with Symfony2Speed up your developments with Symfony2
Speed up your developments with Symfony2Hugo Hamon
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mocking
Konstantin Kudryashov
 
Curso Symfony - Clase 2
Curso Symfony - Clase 2Curso Symfony - Clase 2
Curso Symfony - Clase 2
Javier Eguiluz
 
The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016
Kacper Gunia
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5
Leonardo Proietti
 
Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015
Konstantin Kudryashov
 
Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)
Nikita Popov
 
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
James Titcumb
 

What's hot (20)

New in php 7
New in php 7New in php 7
New in php 7
 
Refactoring using Codeception
Refactoring using CodeceptionRefactoring using Codeception
Refactoring using Codeception
 
Zend Certification Preparation Tutorial
Zend Certification Preparation TutorialZend Certification Preparation Tutorial
Zend Certification Preparation Tutorial
 
Decoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DICDecoupling with Design Patterns and Symfony2 DIC
Decoupling with Design Patterns and Symfony2 DIC
 
PhpSpec 2.0 ilustrated by examples
PhpSpec 2.0 ilustrated by examplesPhpSpec 2.0 ilustrated by examples
PhpSpec 2.0 ilustrated by examples
 
Php functions
Php functionsPhp functions
Php functions
 
Rich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 ApplicationRich Model And Layered Architecture in SF2 Application
Rich Model And Layered Architecture in SF2 Application
 
Symfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il clienteSymfony2, creare bundle e valore per il cliente
Symfony2, creare bundle e valore per il cliente
 
The IoC Hydra
The IoC HydraThe IoC Hydra
The IoC Hydra
 
Php pattern matching
Php pattern matchingPhp pattern matching
Php pattern matching
 
Speed up your developments with Symfony2
Speed up your developments with Symfony2Speed up your developments with Symfony2
Speed up your developments with Symfony2
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mocking
 
Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010Symfony2 - WebExpo 2010
Symfony2 - WebExpo 2010
 
Curso Symfony - Clase 2
Curso Symfony - Clase 2Curso Symfony - Clase 2
Curso Symfony - Clase 2
 
The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016The IoC Hydra - Dutch PHP Conference 2016
The IoC Hydra - Dutch PHP Conference 2016
 
Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5Rich domain model with symfony 2.5 and doctrine 2.5
Rich domain model with symfony 2.5 and doctrine 2.5
 
Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010Symfony2 - OSIDays 2010
Symfony2 - OSIDays 2010
 
Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015
 
Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)
 
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP UK 2017)
 

Similar to Data Validation models

symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207patter
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
Michelangelo van Dam
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Michelangelo van Dam
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8
Michelangelo van Dam
 
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
James Titcumb
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
Hisateru Tanaka
 
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web AppsMashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Bastian Hofmann
 
VPN Access Runbook
VPN Access RunbookVPN Access Runbook
VPN Access RunbookTaha Shakeel
 
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
James Titcumb
 
QA for PHP projects
QA for PHP projectsQA for PHP projects
QA for PHP projects
Michelangelo van Dam
 
Postman On Steroids
Postman On SteroidsPostman On Steroids
Postman On Steroids
Sara Tornincasa
 
An Introduction to Windows PowerShell
An Introduction to Windows PowerShellAn Introduction to Windows PowerShell
An Introduction to Windows PowerShell
Dale Lane
 
Node.js API 서버 성능 개선기
Node.js API 서버 성능 개선기Node.js API 서버 성능 개선기
Node.js API 서버 성능 개선기
JeongHun Byeon
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
Michelangelo van Dam
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
Michelangelo van Dam
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
Michelangelo van Dam
 
Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013
Michelangelo van Dam
 
Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2
Shinya Ohyanagi
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
Nate Abele
 

Similar to Data Validation models (20)

symfony on action - WebTech 207
symfony on action - WebTech 207symfony on action - WebTech 207
symfony on action - WebTech 207
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
 
Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8Unit testing after Zend Framework 1.8
Unit testing after Zend Framework 1.8
 
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
Kicking off with Zend Expressive and Doctrine ORM (Sunshine PHP 2017)
 
関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい関西PHP勉強会 php5.4つまみぐい
関西PHP勉強会 php5.4つまみぐい
 
Mashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web AppsMashing up JavaScript – Advanced Techniques for modern Web Apps
Mashing up JavaScript – Advanced Techniques for modern Web Apps
 
Mashing up JavaScript
Mashing up JavaScriptMashing up JavaScript
Mashing up JavaScript
 
VPN Access Runbook
VPN Access RunbookVPN Access Runbook
VPN Access Runbook
 
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
 
QA for PHP projects
QA for PHP projectsQA for PHP projects
QA for PHP projects
 
Postman On Steroids
Postman On SteroidsPostman On Steroids
Postman On Steroids
 
An Introduction to Windows PowerShell
An Introduction to Windows PowerShellAn Introduction to Windows PowerShell
An Introduction to Windows PowerShell
 
Node.js API 서버 성능 개선기
Node.js API 서버 성능 개선기Node.js API 서버 성능 개선기
Node.js API 서버 성능 개선기
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013Workshop quality assurance for php projects - ZendCon 2013
Workshop quality assurance for php projects - ZendCon 2013
 
Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2
 
The Zen of Lithium
The Zen of LithiumThe Zen of Lithium
The Zen of Lithium
 

Recently uploaded

Final project report on grocery store management system..pdf
Final project report on grocery store management system..pdfFinal project report on grocery store management system..pdf
Final project report on grocery store management system..pdf
Kamal Acharya
 
NO1 Uk best vashikaran specialist in delhi vashikaran baba near me online vas...
NO1 Uk best vashikaran specialist in delhi vashikaran baba near me online vas...NO1 Uk best vashikaran specialist in delhi vashikaran baba near me online vas...
NO1 Uk best vashikaran specialist in delhi vashikaran baba near me online vas...
Amil Baba Dawood bangali
 
H.Seo, ICLR 2024, MLILAB, KAIST AI.pdf
H.Seo,  ICLR 2024, MLILAB,  KAIST AI.pdfH.Seo,  ICLR 2024, MLILAB,  KAIST AI.pdf
H.Seo, ICLR 2024, MLILAB, KAIST AI.pdf
MLILAB
 
AP LAB PPT.pdf ap lab ppt no title specific
AP LAB PPT.pdf ap lab ppt no title specificAP LAB PPT.pdf ap lab ppt no title specific
AP LAB PPT.pdf ap lab ppt no title specific
BrazilAccount1
 
Governing Equations for Fundamental Aerodynamics_Anderson2010.pdf
Governing Equations for Fundamental Aerodynamics_Anderson2010.pdfGoverning Equations for Fundamental Aerodynamics_Anderson2010.pdf
Governing Equations for Fundamental Aerodynamics_Anderson2010.pdf
WENKENLI1
 
Student information management system project report ii.pdf
Student information management system project report ii.pdfStudent information management system project report ii.pdf
Student information management system project report ii.pdf
Kamal Acharya
 
road safety engineering r s e unit 3.pdf
road safety engineering  r s e unit 3.pdfroad safety engineering  r s e unit 3.pdf
road safety engineering r s e unit 3.pdf
VENKATESHvenky89705
 
一比一原版(IIT毕业证)伊利诺伊理工大学毕业证成绩单专业办理
一比一原版(IIT毕业证)伊利诺伊理工大学毕业证成绩单专业办理一比一原版(IIT毕业证)伊利诺伊理工大学毕业证成绩单专业办理
一比一原版(IIT毕业证)伊利诺伊理工大学毕业证成绩单专业办理
zwunae
 
Hybrid optimization of pumped hydro system and solar- Engr. Abdul-Azeez.pdf
Hybrid optimization of pumped hydro system and solar- Engr. Abdul-Azeez.pdfHybrid optimization of pumped hydro system and solar- Engr. Abdul-Azeez.pdf
Hybrid optimization of pumped hydro system and solar- Engr. Abdul-Azeez.pdf
fxintegritypublishin
 
Planning Of Procurement o different goods and services
Planning Of Procurement o different goods and servicesPlanning Of Procurement o different goods and services
Planning Of Procurement o different goods and services
JoytuBarua2
 
ethical hacking-mobile hacking methods.ppt
ethical hacking-mobile hacking methods.pptethical hacking-mobile hacking methods.ppt
ethical hacking-mobile hacking methods.ppt
Jayaprasanna4
 
Sachpazis:Terzaghi Bearing Capacity Estimation in simple terms with Calculati...
Sachpazis:Terzaghi Bearing Capacity Estimation in simple terms with Calculati...Sachpazis:Terzaghi Bearing Capacity Estimation in simple terms with Calculati...
Sachpazis:Terzaghi Bearing Capacity Estimation in simple terms with Calculati...
Dr.Costas Sachpazis
 
Nuclear Power Economics and Structuring 2024
Nuclear Power Economics and Structuring 2024Nuclear Power Economics and Structuring 2024
Nuclear Power Economics and Structuring 2024
Massimo Talia
 
AKS UNIVERSITY Satna Final Year Project By OM Hardaha.pdf
AKS UNIVERSITY Satna Final Year Project By OM Hardaha.pdfAKS UNIVERSITY Satna Final Year Project By OM Hardaha.pdf
AKS UNIVERSITY Satna Final Year Project By OM Hardaha.pdf
SamSarthak3
 
在线办理(ANU毕业证书)澳洲国立大学毕业证录取通知书一模一样
在线办理(ANU毕业证书)澳洲国立大学毕业证录取通知书一模一样在线办理(ANU毕业证书)澳洲国立大学毕业证录取通知书一模一样
在线办理(ANU毕业证书)澳洲国立大学毕业证录取通知书一模一样
obonagu
 
Gen AI Study Jams _ For the GDSC Leads in India.pdf
Gen AI Study Jams _ For the GDSC Leads in India.pdfGen AI Study Jams _ For the GDSC Leads in India.pdf
Gen AI Study Jams _ For the GDSC Leads in India.pdf
gdsczhcet
 
Immunizing Image Classifiers Against Localized Adversary Attacks
Immunizing Image Classifiers Against Localized Adversary AttacksImmunizing Image Classifiers Against Localized Adversary Attacks
Immunizing Image Classifiers Against Localized Adversary Attacks
gerogepatton
 
Fundamentals of Electric Drives and its applications.pptx
Fundamentals of Electric Drives and its applications.pptxFundamentals of Electric Drives and its applications.pptx
Fundamentals of Electric Drives and its applications.pptx
manasideore6
 
Pile Foundation by Venkatesh Taduvai (Sub Geotechnical Engineering II)-conver...
Pile Foundation by Venkatesh Taduvai (Sub Geotechnical Engineering II)-conver...Pile Foundation by Venkatesh Taduvai (Sub Geotechnical Engineering II)-conver...
Pile Foundation by Venkatesh Taduvai (Sub Geotechnical Engineering II)-conver...
AJAYKUMARPUND1
 
DESIGN A COTTON SEED SEPARATION MACHINE.docx
DESIGN A COTTON SEED SEPARATION MACHINE.docxDESIGN A COTTON SEED SEPARATION MACHINE.docx
DESIGN A COTTON SEED SEPARATION MACHINE.docx
FluxPrime1
 

Recently uploaded (20)

Final project report on grocery store management system..pdf
Final project report on grocery store management system..pdfFinal project report on grocery store management system..pdf
Final project report on grocery store management system..pdf
 
NO1 Uk best vashikaran specialist in delhi vashikaran baba near me online vas...
NO1 Uk best vashikaran specialist in delhi vashikaran baba near me online vas...NO1 Uk best vashikaran specialist in delhi vashikaran baba near me online vas...
NO1 Uk best vashikaran specialist in delhi vashikaran baba near me online vas...
 
H.Seo, ICLR 2024, MLILAB, KAIST AI.pdf
H.Seo,  ICLR 2024, MLILAB,  KAIST AI.pdfH.Seo,  ICLR 2024, MLILAB,  KAIST AI.pdf
H.Seo, ICLR 2024, MLILAB, KAIST AI.pdf
 
AP LAB PPT.pdf ap lab ppt no title specific
AP LAB PPT.pdf ap lab ppt no title specificAP LAB PPT.pdf ap lab ppt no title specific
AP LAB PPT.pdf ap lab ppt no title specific
 
Governing Equations for Fundamental Aerodynamics_Anderson2010.pdf
Governing Equations for Fundamental Aerodynamics_Anderson2010.pdfGoverning Equations for Fundamental Aerodynamics_Anderson2010.pdf
Governing Equations for Fundamental Aerodynamics_Anderson2010.pdf
 
Student information management system project report ii.pdf
Student information management system project report ii.pdfStudent information management system project report ii.pdf
Student information management system project report ii.pdf
 
road safety engineering r s e unit 3.pdf
road safety engineering  r s e unit 3.pdfroad safety engineering  r s e unit 3.pdf
road safety engineering r s e unit 3.pdf
 
一比一原版(IIT毕业证)伊利诺伊理工大学毕业证成绩单专业办理
一比一原版(IIT毕业证)伊利诺伊理工大学毕业证成绩单专业办理一比一原版(IIT毕业证)伊利诺伊理工大学毕业证成绩单专业办理
一比一原版(IIT毕业证)伊利诺伊理工大学毕业证成绩单专业办理
 
Hybrid optimization of pumped hydro system and solar- Engr. Abdul-Azeez.pdf
Hybrid optimization of pumped hydro system and solar- Engr. Abdul-Azeez.pdfHybrid optimization of pumped hydro system and solar- Engr. Abdul-Azeez.pdf
Hybrid optimization of pumped hydro system and solar- Engr. Abdul-Azeez.pdf
 
Planning Of Procurement o different goods and services
Planning Of Procurement o different goods and servicesPlanning Of Procurement o different goods and services
Planning Of Procurement o different goods and services
 
ethical hacking-mobile hacking methods.ppt
ethical hacking-mobile hacking methods.pptethical hacking-mobile hacking methods.ppt
ethical hacking-mobile hacking methods.ppt
 
Sachpazis:Terzaghi Bearing Capacity Estimation in simple terms with Calculati...
Sachpazis:Terzaghi Bearing Capacity Estimation in simple terms with Calculati...Sachpazis:Terzaghi Bearing Capacity Estimation in simple terms with Calculati...
Sachpazis:Terzaghi Bearing Capacity Estimation in simple terms with Calculati...
 
Nuclear Power Economics and Structuring 2024
Nuclear Power Economics and Structuring 2024Nuclear Power Economics and Structuring 2024
Nuclear Power Economics and Structuring 2024
 
AKS UNIVERSITY Satna Final Year Project By OM Hardaha.pdf
AKS UNIVERSITY Satna Final Year Project By OM Hardaha.pdfAKS UNIVERSITY Satna Final Year Project By OM Hardaha.pdf
AKS UNIVERSITY Satna Final Year Project By OM Hardaha.pdf
 
在线办理(ANU毕业证书)澳洲国立大学毕业证录取通知书一模一样
在线办理(ANU毕业证书)澳洲国立大学毕业证录取通知书一模一样在线办理(ANU毕业证书)澳洲国立大学毕业证录取通知书一模一样
在线办理(ANU毕业证书)澳洲国立大学毕业证录取通知书一模一样
 
Gen AI Study Jams _ For the GDSC Leads in India.pdf
Gen AI Study Jams _ For the GDSC Leads in India.pdfGen AI Study Jams _ For the GDSC Leads in India.pdf
Gen AI Study Jams _ For the GDSC Leads in India.pdf
 
Immunizing Image Classifiers Against Localized Adversary Attacks
Immunizing Image Classifiers Against Localized Adversary AttacksImmunizing Image Classifiers Against Localized Adversary Attacks
Immunizing Image Classifiers Against Localized Adversary Attacks
 
Fundamentals of Electric Drives and its applications.pptx
Fundamentals of Electric Drives and its applications.pptxFundamentals of Electric Drives and its applications.pptx
Fundamentals of Electric Drives and its applications.pptx
 
Pile Foundation by Venkatesh Taduvai (Sub Geotechnical Engineering II)-conver...
Pile Foundation by Venkatesh Taduvai (Sub Geotechnical Engineering II)-conver...Pile Foundation by Venkatesh Taduvai (Sub Geotechnical Engineering II)-conver...
Pile Foundation by Venkatesh Taduvai (Sub Geotechnical Engineering II)-conver...
 
DESIGN A COTTON SEED SEPARATION MACHINE.docx
DESIGN A COTTON SEED SEPARATION MACHINE.docxDESIGN A COTTON SEED SEPARATION MACHINE.docx
DESIGN A COTTON SEED SEPARATION MACHINE.docx
 

Data Validation models

  • 1. Data validation models Marcin Czarnecki - Tech Lead
  • 3. <form method="post"> <input name="email" type="email"> <input name="username" type="text" minlength="3"> <input name="password" type="password"> <input name="submit" type="submit" value="Register"> </form>
  • 4. <?php require(‘user_functions.php’); if (!empty($_POST['email'])) { if (!empty($_POST['password'])) { if (!empty($_POST['username'])) { save_user($_POST); echo "User created"; exit(); } die("empty username"); } die("empty password"); } die("empty email");
  • 5. <?php use SymfonyComponentValidatorConstraints as Assert; class User { /** * @AssertNotBlank * @AssertString * @AssertEmail */ public $email /** * @AssertNotBlank * @AssertLength(min=“3”) */ public $username; }
  • 6. <?php use AssertAssert; class User { private string $username; private string $email; /* @throw InvalidArgumentException */ public function __construct(string $username, string $email) { Assert::stringNotEmpty($username); Assert::minLength($username, 3); Assert::stringNotEmpty($email); Assert::email($email); $this->username = $username; $this->email = $email; } }
  • 7. create table users ( id bigint not null primary key auto_increment, email varchar(100) not null, username varchar(100) not null, constraint email_unique unique (email), constraint username_unique unique (username) )
  • 8. Two types of data validation
  • 9. Optional section title Syntactic Checks if data has the proper data type and format 2020-02-30 Invalid date 2030-02-03 Looks like a valid date! Semantic Checks if data makes sense in our use case 2030-02-03 Seems to be invalid DoB 1903-01-02 ??? ??? ??? ??? ??? ???
  • 12. { "email": “mczarnecki@example.com" // valid } { "email": 12345679 // invalid - wrong data type }
  • 13. { "email": “mczarnecki@example.com" // valid } { "email": 12345679 // invalid - wrong data type } { "email": “mczarnecki@example" // invalid - wrong domain }
  • 14. { "email": “mczarnecki@example.com" // valid } { "email": 12345679 // invalid - wrong data type } { "email": “mczarnecki@example" // invalid - wrong domain } { "email": “” // invalid - empty string }
  • 15. { "email": “mczarnecki@example.com" // valid } { "email": 12345679 // invalid - wrong data type } { "email": “mczarnecki@example" // invalid - wrong domain } { "email": “” // invalid - empty string } { "email": “mczarnecki+spam@example.com" // valid }
  • 16. Is it so simple? filter_var($email, FILTER_VALIDATE_EMAIL) vs RFC5321
  • 17. mczarnecki(comment)@example.com уникум@из.рф "this is v@lid!"@example.com "()<>[]:,;@"!#$%&'*+-/=?^_`{}| ~.a”@example.org " “@example.org localpart.ending.with.dot.@example.com
  • 18. When should I be more careful about syntax validation? ➔ Integrations with external APIs (for example oAuth) ➔ It is a core of our application Optional section title Usually it will be just an edge case
  • 20. I got mczarnecki@example.com as input, but such user already exists. Is it valid? Optional section title
  • 21. I got mczarnecki@example.com as input, but such user already exists. Is it valid? ➔ Register user context ● Definitely NO! Optional section title
  • 22. I got mczarnecki@example.com as input, but such user already exists. Is it valid? ➔ Register user context ● Definitely NO! ➔ Login user context ● Yes, it is valid Optional section title
  • 23. I got mczarnecki@example.com as input, but such user already exists. Is it valid? ➔ Register user context ● Definitely NO! ➔ Login user context ● Yes, it is valid ➔ Search for friend ● No such validation rule. Optional section title
  • 24. I got mczarnecki@example.com as input, but such user already exists. Is it valid? ➔ Register user context ● Definitely NO! ➔ Login user context ● Yes, it is valid ➔ Search for friend ● No such validation rule. ➔ Send order confirmation email ● Yes, it is required to exist in database Optional section title
  • 27. As soon as possible Before deserialisation or just after it. Optional section title
  • 29. <?php use SymfonyComponentValidatorConstraints as Assert; class RegisterUserRequest { /** * @AssertNotBlank * @AssertString */ public $email /** * @AssertNotBlank * @AssertLength(min=“3”) */ public $username; }
  • 30. Make sure that you will always operate on valid object Use Argument Resolver and kernel.exception listener to handle invalid requests Optional section title
  • 31. <?php use SymfonyComponentValidatorConstraints as Assert; class RegisterUserRequestResolver implements ArgumentValueResolverInterface { private SerializerInterface $serializer; private ValidatorInterface $validator; public function __construct( SerializerInterface $serializer, ValidatorInterface $validator ) { $this->serializer = $serializer; $this->validator = $validator; }
  • 32. <?php class RegisterUserRequestResolver implements ArgumentValueResolverInterface { public function supports(Request $request, ArgumentMetadata $argument) { return RegisterUserRequest::class === $argument->getType(); } public function resolve(Request $request, ArgumentMetadata $argument) { $dto = $this->serializer->deserialize($request->getContent(), RegisterUserRequest::class, 'json'); $errors = $this->validator->validate($dto); if($errors->count()){ throw new Exception((string)$errors); } yield $dto; } }
  • 33. <?php class ExceptionListener { public function onKernelException(ExceptionEvent $event) { $exception = $event->getThrowable(); $response = new Response(); $response->setContent($exception->getMessage()); $response->setStatusCode(Response::HTTP_BAD_REQUEST); $event->setResponse($response); } }
  • 34. <?php class UserController { public function index(RegisterUserRequest $request) { $this->usersService->createUser( $request->email, $request->username, ); return new Response('', Response::HTTP_CREATED); } }
  • 36. Domain model should be always valid To keep your code DRY most of the semantic validation should take place in the application / domain layer. Optional section title
  • 37. <?php class UserController { public function index(RegisterUserRequest $request) { $this->usersService->createUser( $request->email, $request->username, ); return new Response('', Response::HTTP_CREATED); } }
  • 38. <?php class UserController { public function index(RegisterUserRequest $request) { $this->usersService->createUser( new Username($request->username), new Email($request->email), ); return new Response('', Response::HTTP_CREATED); } }
  • 39. <?php use WebmozartAssertAssert; class Email { private string $email; public function __construct(string $email) { Assert::email($email); $this->email = $email; } }
  • 40. <?php class UserService { public function createUser(Username $username, Email $email) { if($this->usersRepository->findByEmail($email)){ throw new UserAlreadyExists(); } if($this->usersRepository->findByUsername($username)){ throw new UserAlreadyExists(); } $this->usersRepository->add(new User( $email, $username )); }
  • 41. <?php use WebmozartAssertAssert; class User { private string $email; public function __construct(string $email) { Assert::email($email); $this->email = $email; } }
  • 43. +-------------------------+----------+----------+ | benchmark | mean | mem_peak | +-------------------------+----------+----------+ | BeberleiAssertBench | 4.490μs | 1.237mb | | WebmozartValidatorBench | 4.376μs | 1.200mb | | BeberleiLazyAssertBench | 20.786μs | 1.295mb | | Symfony4ValidatorBench | 25.435μs | 1.384mb | | Symfony5ValidatorBench | 30.400μs | 1.441mb | | Symfony6ValidatorBench | 32.061μs | 1.366mb | | LaravelBench | 15.470μs | 2.339mb | | LaminasBench | 97.789μs | 1.296mb | +-------------------------+----------+----------+
  • 44. +-------------------------+----------+----------+ | benchmark | mean | mem_peak | +-------------------------+----------+----------+ | BeberleiAssertBench | 4.490μs | 1.237mb | | WebmozartValidatorBench | 4.376μs | 1.200mb | | BeberleiLazyAssertBench | 20.786μs | 1.295mb | | Symfony4ValidatorBench | 25.435μs | 1.384mb | | Symfony5ValidatorBench | 30.400μs | 1.441mb | | Symfony6ValidatorBench | 32.061μs | 1.366mb | | LaravelBench | 15.470μs | 2.339mb | | LaminasBench | 97.789μs | 1.296mb | +-------------------------+----------+----------+
  • 45. +-------------------------+----------+----------+ | benchmark | mean | mem_peak | +-------------------------+----------+----------+ | BeberleiAssertBench | 4.490μs | 1.237mb | | WebmozartValidatorBench | 4.376μs | 1.200mb | | BeberleiLazyAssertBench | 20.786μs | 1.295mb | | Symfony4ValidatorBench | 25.435μs | 1.384mb | | Symfony5ValidatorBench | 30.400μs | 1.441mb | | Symfony6ValidatorBench | 32.061μs | 1.366mb | | LaravelBench | 15.470μs | 2.339mb | | LaminasBench | 97.789μs | 1.296mb | +-------------------------+----------+----------+
  • 46. +-------------------------+----------+----------+ | benchmark | mean | mem_peak | +-------------------------+----------+----------+ | BeberleiAssertBench | 4.490μs | 1.237mb | | WebmozartValidatorBench | 4.376μs | 1.200mb | | BeberleiLazyAssertBench | 20.786μs | 1.295mb | | Symfony4ValidatorBench | 25.435μs | 1.384mb | | Symfony5ValidatorBench | 30.400μs | 1.441mb | | Symfony6ValidatorBench | 32.061μs | 1.366mb | | LaravelBench | 15.470μs | 2.339mb | | LaminasBench | 97.789μs | 1.296mb | +-------------------------+----------+----------+
  • 49. Take away ➔Syntactic validation should be done as soon as possible ➔Semantic validation should be implemented in the application / domain level ➔We should avoid of operating on incorrect objects ➔Always validate your input :) Optional section title