# Validation API Platform takes care of validating the data sent to the API by the client (usually user data entered through forms). By default, the framework relies on [the powerful Symfony Validator Component](http://symfony.com/doc/current/validation.html) for this task, but you can replace it by your preferred validation library such as [the PHP filter extension](http://php.net/manual/en/intro.filter.php) if you want to. ## Validating Submitted Data Validating submitted data is as simple as adding [Symfony's built-in constraints](http://symfony.com/doc/current/reference/constraints.html) or [custom constraints](http://symfony.com/doc/current/validation/custom_constraint.html) directly in classes marked with the `@ApiResource` annotation: ```php context->buildViolation($constraint->message)->addViolation(); } } } ``` If the data submitted by the client is invalid, the HTTP status code will be set to `400 Bad Request` and the response's body will contain the list of violations serialized in a format compliant with the requested one. For instance, a validation error will look like the following if the requested format is JSON-LD (the default): ```json { "@context": "/contexts/ConstraintViolationList", "@type": "ConstraintViolationList", "hydra:title": "An error occurred", "hydra:description": "properties: The product must have the minimal properties required (\"description\", \"price\")", "violations": [ { "propertyPath": "properties", "message": "The product must have the minimal properties required (\"description\", \"price\")" } ] } ``` Take a look at the [Errors Handling guide](errors.md) to learn how API Platform converts PHP exceptions like validation errors to HTTP errors. ## Using Validation Groups Without specific configuration, the default validation group is always used, but this behavior is customizable: the framework is able to leverage Symfony's [validation groups](http://symfony.com/doc/current/book/validation.html#validation-groups). You can configure the groups you want to use when the validation occurs directly through the `ApiResource` annotation: ```php authorizationChecker = $authorizationChecker; } public function __invoke(Book $book): array { return $this->authorizationChecker->isGranted('ROLE_ADMIN', $book) ? ['a', 'b'] : ['a']; } } ``` This class selects the groups to apply based on the role of the current user: if the current user has the `ROLE_ADMIN` role, groups `a` and `b` are returned. In other cases, just `a` is returned. This class is automatically registered as a service thanks to [the autowiring feature of the Symfony Dependency Injection Component](https://symfony.com/doc/current/service_container/autowiring.html). Just note that this service must be public. Then, configure the entity class to use this service to retrieve validation groups: ```php getValues()`, you should define your validation on the getter instead of the property. For example: ```xml ``` ```php final class Brand { // ... public function __construct() { $this->cars = new ArrayCollection(); } /** * @Assert\Valid */ public function getCars() { return $this->cars->getValues(); } } ``` ## Open Vocabulary Generated from Validation Metadata API Platform automatically detects Symfony's built-in validators and generates schema.org IRI metadata accordingly. This allows for rich clients such as the Admin component to infer the field types for most basic use cases. The following validation constraints are covered: Constraints | Vocabulary | --------------------------------------------------------------------------------------|-----------------------------------| [`Url`](https://symfony.com/doc/current/reference/constraints/Url.html) | `http://schema.org/url` | [`Email`](https://symfony.com/doc/current/reference/constraints/Email.html) | `http://schema.org/email` | [`Uuid`](https://symfony.com/doc/current/reference/constraints/Uuid.html) | `http://schema.org/identifier` | [`CardScheme`](https://symfony.com/doc/current/reference/constraints/CardScheme.html) | `http://schema.org/identifier` | [`Bic`](https://symfony.com/doc/current/reference/constraints/Bic.html) | `http://schema.org/identifier` | [`Iban`](https://symfony.com/doc/current/reference/constraints/Iban.html) | `http://schema.org/identifier` | [`Date`](https://symfony.com/doc/current/reference/constraints/Date.html) | `http://schema.org/Date` | [`DateTime`](https://symfony.com/doc/current/reference/constraints/DateTime.html) | `http://schema.org/DateTime` | [`Time`](https://symfony.com/doc/current/reference/constraints/Time.html) | `http://schema.org/Time` | [`Image`](https://symfony.com/doc/current/reference/constraints/Image.html) | `http://schema.org/image` | [`File`](https://symfony.com/doc/current/reference/constraints/File.html) | `http://schema.org/MediaObject` | [`Currency`](https://symfony.com/doc/current/reference/constraints/Currency.html) | `http://schema.org/priceCurrency` | [`Isbn`](https://symfony.com/doc/current/reference/constraints/Isbn.html) | `http://schema.org/isbn` | [`Issn`](https://symfony.com/doc/current/reference/constraints/Issn.html) | `http://schema.org/issn` |