• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

api-platform / core / 10749392760

07 Sep 2024 06:39AM UTC coverage: 7.646%. Remained the same
10749392760

push

github

soyuka
test: remove hydra prefix from guides

0 of 21 new or added lines in 6 files covered. (0.0%)

6834 existing lines in 225 files now uncovered.

12538 of 163980 relevant lines covered (7.65%)

22.78 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/docs/guides/validate-incoming-data.php
1
<?php
2
// ---
3
// slug: validate-incoming-data
4
// name: Validate incoming data
5
// executable: true
6
// position: 5
7
// tags: validation
8
// ---
9

10
// When processing the incoming request, when creating or updating content, API-Platform will validate the
11
// incoming content. It will use the [Symfony's validator](https://symfony.com/doc/current/validation.html).
12
//
13
// API Platform takes care of validating the data sent to the API by the client (usually user data entered through forms).
14
// 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 with your preferred validation library such as the [PHP filter extension](https://www.php.net/manual/en/intro.filter.php) if you want to.
15
// Validation is called when handling a POST, PATCH, PUT request as follows :
16

17
// graph LR
18
// Request --> Deserialization
19
// Deserialization --> Validation
20
// Validation --> Persister
21
// Persister --> Serialization
22
// Serialization --> Response
23

24
// In this guide we're going to use [Symfony's built-in constraints](http://symfony.com/doc/current/reference/constraints.html) and a [custom constraint](http://symfony.com/doc/current/validation/custom_constraint.html). Let's start by shaping our to-be-validated resource:
25

26
namespace App\Entity {
27
    use ApiPlatform\Metadata\ApiResource;
28
    // A custom constraint.
29
    use App\Validator\Constraints\MinimalProperties;
30
    use Doctrine\ORM\Mapping as ORM;
31
    // Symfony's built-in constraints
32
    use Symfony\Component\Validator\Constraints as Assert;
33

34
    /**
35
     * A product.
36
     */
37
    #[ORM\Entity]
38
    #[ApiResource]
39
    class Product
40
    {
41
        #[ORM\Id, ORM\Column, ORM\GeneratedValue]
42
        private ?int $id = null;
43

44
        #[ORM\Column]
45
        #[Assert\NotBlank]
46
        public string $name;
47

48
        /**
49
         * @var string[] Describe the product
50
         */
51
        #[MinimalProperties]
52
        #[ORM\Column(type: 'json')]
53
        public $properties;
54

55
        public function getId(): ?int
56
        {
57
            return $this->id;
×
58
        }
59
    }
60
}
61

62
// The `MinimalProperties` constraint will check that the `properties` data holds at least two values: description and price.
63
// We start by creating the constraint:
64

65
namespace App\Validator\Constraints {
66
    use Symfony\Component\Validator\Constraint;
67

68
    #[\Attribute]
69
    class MinimalProperties extends Constraint
70
    {
71
        public $message = 'The product must have the minimal properties required ("description", "price")';
72
    }
73
}
74

75
// Then the validator following [Symfony's naming conventions](https://symfony.com/doc/current/validation/custom_constraint.html#creating-the-validator-itself)
76

77
namespace App\Validator\Constraints {
78
    use Symfony\Component\Validator\Constraint;
79
    use Symfony\Component\Validator\ConstraintValidator;
80

81
    final class MinimalPropertiesValidator extends ConstraintValidator
82
    {
83
        public function validate($value, Constraint $constraint): void
84
        {
85
            if (!\array_key_exists('description', $value) || !\array_key_exists('price', $value)) {
×
86
                $this->context->buildViolation($constraint->message)->addViolation();
×
87
            }
88
        }
89
    }
90
}
91

92
namespace DoctrineMigrations {
93
    use Doctrine\DBAL\Schema\Schema;
94
    use Doctrine\Migrations\AbstractMigration;
95

96
    final class Migration extends AbstractMigration
97
    {
98
        public function up(Schema $schema): void
99
        {
100
            $this->addSql('CREATE TABLE product (id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name VARCHAR(255) NOT NULL, properties CLOB NOT NULL)');
×
101
        }
102
    }
103
}
104

105
namespace App\Playground {
106
    use Symfony\Component\HttpFoundation\Request;
107

108
    function request(): Request
109
    {
110
        return Request::create(
×
111
            uri: '/products',
×
112
            method: 'POST',
×
113
            server: [
×
114
                'CONTENT_TYPE' => 'application/ld+json',
×
115
                'HTTP_ACCEPT' => 'application/ld+json',
×
116
            ],
×
117
            content: '{"name": "test", "properties": {"description": "Test product"}}'
×
118
        );
×
119
    }
120
}
121

122
namespace App\Tests {
123
    use ApiPlatform\Playground\Test\TestGuideTrait;
124
    use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
125

126
    final class BookTest extends ApiTestCase
127
    {
128
        use TestGuideTrait;
129

130
        public function testValidation(): void
131
        {
132
            $response = static::createClient()->request(method: 'POST', url: '/products', options: [
×
133
                'json' => ['name' => 'test', 'properties' => ['description' => 'foo']],
×
134
                'headers' => ['content-type' => 'application/ld+json'],
×
135
            ]);
×
136

137
            // If the data submitted by the client is invalid, the HTTP status code will be set to 422 Unprocessable Entity 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):
138
            // ```json
139
            // {
140
            //   "@context": "/contexts/ConstraintViolationList",
141
            //   "@type": "ConstraintViolationList",
142
            //   "title": "An error occurred",
143
            //   "description": "properties: The product must have the minimal properties required (\"description\", \"price\")",
144
            //   "violations": [
145
            //     {
146
            //       "propertyPath": "properties",
147
            //       "message": "The product must have the minimal properties required (\"description\", \"price\")"
148
            //     }
149
            //   ]
150
            //  }
151
            // ```
152
            $this->assertResponseStatusCodeSame(422);
×
153
            $this->assertJsonContains([
×
NEW
154
                'description' => 'properties: The product must have the minimal properties required ("description", "price")',
×
155
                'title' => 'An error occurred',
×
156
                'violations' => [
×
157
                    ['propertyPath' => 'properties', 'message' => 'The product must have the minimal properties required ("description", "price")'],
×
158
                ],
×
159
            ]);
×
160
        }
161
    }
162
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc