Skip to content

Commit 334f481

Browse files
committed
Docuemtn filters/parameters etc.
1 parent e69ae7f commit 334f481

File tree

2 files changed

+363
-0
lines changed

2 files changed

+363
-0
lines changed

core/filters.md

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,114 @@ For the **specific filters documentation**, please refer to the following pages,
2323

2424
You can declare parameters on a Resource or an Operation through the `parameters` property.
2525

26+
The `ParameterProvider` is at the heart of parameter handling in API Platform. When a request comes in, this provider iterates through all the parameters defined for the operation. For each parameter, it performs the following steps:
27+
28+
1. **Value Extraction**: It retrieves the parameter's value from the request. For `QueryParameter`, it looks in the query string, and for `HeaderParameter`, it checks the request headers.
29+
2. **Default Value**: If the parameter is not present in the request, the provider checks if a default value is defined in the parameter's schema. If so, it uses the default value.
30+
3. **Value Setting**: The extracted or default value is then set on the `Parameter` object.
31+
4. **Custom Provider**: If the parameter has a custom provider defined (via the `provider` option), the `ParameterProvider` will invoke it. This allows for custom logic to be executed, such as modifying the `Operation` object based on the parameter's value.
32+
33+
### Strict Parameter Validation
34+
35+
API Platform supports strict parameter validation. When enabled on an `HttpOperation` (by setting `strictQueryParameterValidation` to `true`), the `ParameterProvider` will check if the request contains any query parameters that are not explicitly defined for the operation. If it finds any unknown parameters, it will throw a `ParameterNotSupportedException`, effectively rejecting the request. This helps to ensure that clients are only using the parameters that are supported by the API.
36+
37+
### Path Parameters as Links
38+
39+
In API Platform, path parameters are not just simple placeholders in the URL; they are powerful constructs represented by `ApiPlatform\Metadata\Link` objects. These `Link` objects allow you to define the relationship between the path parameter and the resource being requested. This is especially useful for fetching related resources and for filtering collections based on path parameters.
40+
41+
For example, consider a URL like `/companies/{companyId}/employees`. The `{companyId}` path parameter can be configured as a `Link` to filter the `Employee` collection and return only the employees belonging to the specified company.
42+
43+
Here's how you can configure a path parameter as a `Link`:
44+
45+
```php
46+
namespace App\ApiResource;
47+
48+
use ApiPlatform\Metadata\ApiResource;
49+
use ApiPlatform\Metadata\GetCollection;
50+
use ApiPlatform\Metadata\Link;
51+
use App\Entity\Company;
52+
53+
#[ApiResource(
54+
operations: [
55+
new GetCollection(
56+
uriTemplate: '/companies/{companyId}/employees',
57+
uriVariables: [
58+
'companyId' => new Link(toProperty: 'company', fromClass: Company::class)
59+
]
60+
)
61+
]
62+
)]
63+
class Employee
64+
{
65+
// ...
66+
}
67+
```
68+
69+
In this example, the `companyId` path parameter is linked to the `company` property of the `Employee` resource. When a request is made to `/companies/1/employees`, API Platform will automatically filter the `Employee` collection to return only the employees where the `company` property is the `Company` with an ID of 1.
70+
71+
This filtering is made possible by the `ApiPlatform\Doctrine\Orm\Extension\ParameterExtension`. This extension inspects the `Link` objects defined for an operation and, if a `toProperty` is specified, it automatically adds a `WHERE` clause to the Doctrine query to filter the results.
72+
73+
You can also use IRIs (Internationalized Resource Identifiers) in your path parameters. For example, you could have a URL like `/employees/by-company/{companyIri}`. In this case, you would configure the `Link` to use the IRI to fetch the related company.
74+
75+
Here's an example of how to use an IRI as a path parameter:
76+
77+
```php
78+
namespace App\ApiResource;
79+
80+
use ApiPlatform\Metadata\ApiResource;
81+
use ApiPlatform\Metadata\Get;
82+
use ApiPlatform\Metadata\Link;
83+
use App\Entity\Dummy;
84+
85+
#[ApiResource(
86+
operations: [
87+
new Get(
88+
uriTemplate: '/with_parameters_iris/{dummyIri}',
89+
uriVariables: [
90+
'dummyIri' => new Link(fromClass: Dummy::class)
91+
]
92+
)
93+
]
94+
)]
95+
class WithParameters
96+
{
97+
// ...
98+
}
99+
```
100+
101+
In this example, a GET request to `/with_parameters_iris/dummies/1` would fetch the `Dummy` entity with ID 1 and use it as the `dummyIri` parameter.
102+
103+
You can also use path parameters to filter collections of resources. For example, you could have a URL like `/with_parameters_links?dummy=1`. This would fetch a collection of resources, filtered by the `dummy` parameter.
104+
105+
Here's an example of how to use a path parameter to filter a collection:
106+
107+
```php
108+
namespace App\ApiResource;
109+
110+
use ApiPlatform\Metadata\ApiResource;
111+
use ApiPlatform\Metadata\GetCollection;
112+
use ApiPlatform\Metadata\Link;
113+
use App\Entity\Dummy;
114+
115+
#[ApiResource(
116+
operations: [
117+
new GetCollection(
118+
uriTemplate: '/with_parameters_links',
119+
uriVariables: [
120+
'dummy' => new Link(fromClass: Dummy::class)
121+
]
122+
)
123+
]
124+
)]
125+
class WithParameters
126+
{
127+
// ...
128+
}
129+
```
130+
131+
In this example, a GET request to `/with_parameters_links?dummy=1` would fetch a collection of `WithParameters` resources, filtered by the `dummy` parameter with the value `1`.
132+
133+
26134
```php
27135
namespace App\ApiResource;
28136

@@ -176,6 +284,13 @@ class Book {
176284

177285
A parameter is quite close to its documentation, and you can specify the JSON Schema and/or the OpenAPI documentation:
178286

287+
The documentation for parameters is generated automatically based on their definitions. This is made possible by two key interfaces:
288+
289+
* **`JsonSchemaFilterInterface`**: Filters implementing this interface can provide a JSON Schema for the parameters they handle. This schema is used to generate the Hydra documentation.
290+
* **`OpenApiParameterFilterInterface`**: Filters implementing this interface can provide an array of OpenAPI `Parameter` objects. This is used to generate the OpenAPI (Swagger) documentation.
291+
292+
By implementing these interfaces in your custom filters, you can ensure that your parameters are accurately and automatically documented in both Hydra and OpenAPI.
293+
179294
```php
180295
namespace App\ApiResource;
181296

core/parameters.md

Lines changed: 248 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,248 @@
1+
# Using Parameters
2+
3+
API Platform provides a powerful and flexible parameter system that allows you to control various aspects of your API, from filtering and pagination to serialization and security. This guide will walk you through the different types of parameters available and how to use them effectively.
4+
5+
## Query Parameters
6+
7+
Query parameters are the most common type of parameter. They are passed in the URL's query string (e.g., `?page=2`). You can define query parameters on a resource or on a specific operation using the `#[QueryParameter]` attribute.
8+
9+
Here's an example of how to define a query parameter for pagination:
10+
11+
```php
12+
<?php
13+
// api/src/ApiResource/Book.php
14+
15+
namespace App\ApiResource;
16+
17+
use ApiPlatform\Metadata\ApiResource;
18+
use ApiPlatform\Metadata\GetCollection;
19+
use ApiPlatform\Metadata\QueryParameter;
20+
21+
#[ApiResource(
22+
operations: [
23+
new GetCollection(
24+
parameters: [
25+
'page' => new QueryParameter(description: 'The page number.', schema: ['type' => 'integer', 'default' => 1])
26+
]
27+
)
28+
]
29+
)]
30+
class Book
31+
{
32+
// ...
33+
}
34+
```
35+
36+
In this example, we've defined a `page` query parameter for the `GetCollection` operation. The parameter has a description, a schema that specifies its type and default value.
37+
38+
## Header Parameters
39+
40+
Header parameters are passed in the request headers (e.g., `Authorization: Bearer <token>`). You can define header parameters using the `#[HeaderParameter]` attribute.
41+
42+
Here's an example of how to define a header parameter for an API key:
43+
44+
```php
45+
<?php
46+
// api/src/ApiResource/Book.php
47+
48+
namespace App\ApiResource;
49+
50+
use ApiPlatform\Metadata\ApiResource;
51+
use ApiPlatform\Metadata\Get;
52+
use ApiPlatform\Metadata\HeaderParameter;
53+
54+
#[ApiResource(
55+
operations: [
56+
new Get(
57+
parameters: [
58+
'API_KEY' => new HeaderParameter(description: 'Your API key.', required: true, schema: ['type' => 'string'])
59+
]
60+
)
61+
]
62+
)]
63+
class Book
64+
{
65+
// ...
66+
}
67+
```
68+
69+
In this example, we've defined an `API_KEY` header parameter for the `Get` operation. The parameter is required and has a schema that specifies its type.
70+
71+
## Path Parameters as Links
72+
73+
Path parameters are the dynamic parts of the URL (e.g., the `{id}` in `/books/{id}`). In API Platform, path parameters are represented by `ApiPlatform\Metadata\Link` objects. These objects allow you to define the relationship between the path parameter and the resource being requested.
74+
75+
This is particularly useful for fetching related resources and for filtering collections based on path parameters.
76+
77+
Here's an example of how to use a path parameter to fetch a collection of books by a specific author:
78+
79+
```php
80+
<?php
81+
// api/src/ApiResource/Book.php
82+
83+
namespace App\ApiResource;
84+
85+
use ApiPlatform\Metadata\ApiResource;
86+
use ApiPlatform\Metadata\GetCollection;
87+
use ApiPlatform\Metadata\Link;
88+
use App\Entity\Author;
89+
90+
#[ApiResource(
91+
operations: [
92+
new GetCollection(
93+
uriTemplate: '/authors/{authorId}/books',
94+
uriVariables: [
95+
'authorId' => new Link(toProperty: 'author', fromClass: Author::class)
96+
]
97+
)
98+
]
99+
)]
100+
class Book
101+
{
102+
public int $id;
103+
public string $title;
104+
public Author $author;
105+
}
106+
```
107+
108+
In this example, the `authorId` path parameter is linked to the `author` property of the `Book` resource. When a request is made to `/authors/1/books`, API Platform will automatically filter the `Book` collection to return only the books where the `author` property is the `Author` with an ID of 1.
109+
110+
This filtering is made possible by the `ApiPlatform\Doctrine\Orm\Extension\ParameterExtension`. This extension inspects the `Link` objects defined for an operation and, if a `toProperty` is specified, it automatically adds a `WHERE` clause to the Doctrine query to filter the results.
111+
112+
## Parameter Validation
113+
114+
API Platform automatically validates parameters based on their schema definition. For example, if you define a parameter with `['type' => 'integer']`, API Platform will ensure that the value passed in the request is a valid integer.
115+
116+
You can also use [Symfony's validation constraints](https://symfony.com/doc/current/validation.html) to define more complex validation rules.
117+
118+
Here's an example of how to use validation constraints on a parameter:
119+
120+
```php
121+
<?php
122+
// api/src/ApiResource/Book.php
123+
124+
namespace App\ApiResource;
125+
126+
use ApiPlatform\Metadata\ApiResource;
127+
use ApiPlatform\Metadata\Get;
128+
use ApiPlatform\Metadata\QueryParameter;
129+
use Symfony\Component\Validator\Constraints as Assert;
130+
131+
#[ApiResource(
132+
operations: [
133+
new Get(
134+
parameters: [
135+
'rating' => new QueryParameter(
136+
description: 'The rating of the book.',
137+
schema: ['type' => 'integer'],
138+
constraints: [
139+
new Assert\Range(min: 1, max: 5)
140+
]
141+
)
142+
]
143+
)
144+
]
145+
)]
146+
class Book
147+
{
148+
// ...
149+
}
150+
```
151+
152+
In this example, we've added a `Range` constraint to the `rating` parameter, ensuring that its value is between 1 and 5.
153+
154+
## Parameter Security
155+
156+
You can secure your parameters using the `security` option. This allows you to restrict access to parameters based on the user's roles or other conditions.
157+
158+
Here's an example of how to secure a parameter:
159+
160+
```php
161+
<?php
162+
// api/src/ApiResource/Book.php
163+
164+
namespace App\ApiResource;
165+
166+
use ApiPlatform\Metadata\ApiResource;
167+
use ApiPlatform\Metadata\Get;
168+
use ApiPlatform\Metadata\QueryParameter;
169+
170+
#[ApiResource(
171+
operations: [
172+
new Get(
173+
parameters: [
174+
'show_unpublished' => new QueryParameter(
175+
description: 'Whether to show unpublished books.',
176+
schema: ['type' => 'boolean'],
177+
security: "is_granted('ROLE_ADMIN')"
178+
)
179+
]
180+
)
181+
]
182+
)]
183+
class Book
184+
{
185+
// ...
186+
}
187+
```
188+
189+
In this example, the `show_unpublished` parameter can only be used by users with the `ROLE_ADMIN` role.
190+
191+
## Custom Parameter Providers
192+
193+
For more advanced use cases, you can create your own custom parameter providers. A parameter provider is a class that implements the `ApiPlatform\State\ParameterProviderInterface`. This interface has a `provide` method that allows you to implement your own logic for handling a parameter.
194+
195+
Here's an example of a custom parameter provider that modifies the serialization context based on a query parameter:
196+
197+
```php
198+
<?php
199+
// src/Parameter/GroupsParameterProvider.php
200+
201+
namespace App\Parameter;
202+
203+
use ApiPlatform\State\ParameterProviderInterface;
204+
use ApiPlatform\Metadata\Parameter;
205+
use ApiPlatform\Metadata\HttpOperation;
206+
207+
class GroupsParameterProvider implements ParameterProviderInterface
208+
{
209+
public function provide(Parameter $parameter, array $uriVariables = [], array $context = []): HttpOperation
210+
{
211+
$request = $context['request'];
212+
return $context['operation']->withNormalizationContext(['groups' => $request->query->all('groups')]);
213+
}
214+
}
215+
```
216+
217+
You can then use this provider on a parameter:
218+
219+
```php
220+
<?php
221+
// api/src/ApiResource/Book.php
222+
223+
namespace App\ApiResource;
224+
225+
use ApiPlatform\Metadata\ApiResource;
226+
use ApiPlatform\Metadata\Get;
227+
use ApiPlatform\Metadata\QueryParameter;
228+
use App\Parameter\GroupsParameterProvider;
229+
230+
#[ApiResource(
231+
operations: [
232+
new Get(
233+
parameters: [
234+
'groups' => new QueryParameter(
235+
description: 'The serialization groups to use.',
236+
provider: GroupsParameterProvider::class
237+
)
238+
]
239+
)
240+
]
241+
)]
242+
class Book
243+
{
244+
// ...
245+
}
246+
```
247+
248+
In this example, when the `groups` parameter is present in the request, the `GroupsParameterProvider` will be invoked, and it will modify the serialization context to use the specified groups.

0 commit comments

Comments
 (0)