Skip to content

Commit ca02e93

Browse files
committed
docs(config): clarify default-order vs operation-order precedence
`api_platform.defaults.order` prepends its keys to any operation-level `order` (via `array_merge($globalDefault, $operationOrder)`) rather than acting as a fallback that yields to the operation. Correct the inaccurate "overrides" claim in the existing paragraph and add a new section that explains the merge semantics, shows a concrete example with resulting ORDER BY, and documents the escape hatch (omit the global default and set order per-operation, or replace OrderExtension). Refs api-platform/core#8156 (documents intentional behaviour).
1 parent 925f3b6 commit ca02e93

1 file changed

Lines changed: 54 additions & 2 deletions

File tree

core/default-order.md

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,7 @@ App\ApiResource\Book:
114114

115115
</code-selector>
116116

117-
Another possibility is to apply the default order for a specific collection operation, which will
118-
override the global default order configuration.
117+
Another possibility is to apply the default order for a specific collection operation.
119118

120119
<code-selector>
121120

@@ -163,3 +162,56 @@ App\ApiResource\Book:
163162
```
164163

165164
</code-selector>
165+
166+
## Global Default Order and Operation Order Precedence
167+
168+
`api_platform.defaults.order` (set under the `defaults:` key in `api_platform.yaml`) applies an
169+
order to every operation. It is not a fallback that yields to operation-level configuration — it is
170+
a cross-cutting invariant that is always applied.
171+
172+
When an operation also defines its own `order`, the two arrays are **merged**: the global default
173+
keys come first, followed by the operation-level keys. This means the global default takes priority
174+
in the SQL `ORDER BY` clause, and the operation-level keys act as tie-breakers.
175+
176+
For example, given this configuration:
177+
178+
```yaml
179+
# config/packages/api_platform.yaml
180+
api_platform:
181+
defaults:
182+
order:
183+
createdAt: DESC
184+
```
185+
186+
And this resource:
187+
188+
```php
189+
<?php
190+
// api/src/ApiResource/Book.php
191+
namespace App\ApiResource;
192+
193+
use ApiPlatform\Metadata\ApiResource;
194+
use ApiPlatform\Metadata\GetCollection;
195+
196+
#[ApiResource(operations: [
197+
new GetCollection(order: ['title' => 'ASC']),
198+
])]
199+
class Book
200+
{
201+
public \DateTimeImmutable $createdAt;
202+
public string $title;
203+
}
204+
```
205+
206+
The effective order for the `GetCollection` operation is
207+
`['createdAt' => 'DESC', 'title' => 'ASC']`, producing `ORDER BY createdAt DESC, title ASC`. The
208+
global default is prepended to the operation-level order, not replaced by it.
209+
210+
This behavior is intentional. `api_platform.defaults.order` is designed for invariants such as
211+
"always order by `createdAt DESC`" that must hold across all collections regardless of which
212+
operation is called.
213+
214+
**If you want an operation to use a specific order with no global keys prepended**, do not set
215+
`api_platform.defaults.order`. Instead, set the `order` explicitly on each operation or resource
216+
where you need it. For more control over ordering logic, implement a custom
217+
[Doctrine ORM extension](extensions.md) that replaces the built-in `OrderExtension`.

0 commit comments

Comments
 (0)