Skip to content

Commit 8746a41

Browse files
committed
Start to update creating_new_rest_resource.md
1 parent 749ee2e commit 8746a41

File tree

3 files changed

+53
-50
lines changed

3 files changed

+53
-50
lines changed

code_samples/api/rest_api/src/Rest/Controller/DefaultController.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace App\Rest\Controller;
44

5+
use ApiPlatform\Metadata\Get;
56
use ApiPlatform\Metadata\Post;
67
use ApiPlatform\OpenApi\Factory\OpenApiFactory;
78
use ApiPlatform\OpenApi\Model;

code_samples/api/rest_api/src/Rest/Serializer/GreetingNormalizer.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ public function supportsNormalization(mixed $data, ?string $format = null)
2525
public function normalize(mixed $object, ?string $format = null, array $context = []): array
2626
{
2727
$data = [
28-
'salutation' => $object->salutation,
29-
'recipient' => $object->recipient,
30-
'sentence' => "{$object->salutation} {$object->recipient}",
28+
'Salutation' => $object->salutation,
29+
'Recipient' => $object->recipient,
30+
'Sentence' => "{$object->salutation} {$object->recipient}",
3131
];
3232
if ('json' === $format) {
3333
$data = ['Greeting' => $data];

docs/api/rest_api/extending_rest_api/creating_new_rest_resource.md

Lines changed: 49 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ To create a new REST resource, you need to prepare:
88

99
- the REST route leading to a controller action
1010
- the controller and its action
11-
- one or several `InputParser` objects if the controller needs to receive a payload to treat, one or several value classes to represent this payload and potentially one or several new media types to type this payload in the `Content-Type` header (optional)
12-
- one or several new value classes to represent the controller action result, their `ValueObjectVisitor` to help the generator to turn this into XML or JSON and potentially one or several new media types to claim in the `Accept` header the desired value (optional)
11+
- one or several input denormalizers if the controller needs to receive a payload to treat, one or several value classes to represent this payload, and potentially one or several new media types to type this payload in the `Content-Type` header (optional)
12+
- one or several new value classes to represent the controller action result, their normalizers to help the generator to turn this into XML or JSON, and potentially one or several new media types to claim in the `Accept` header the desired value (optional)
1313
- the addition of this resource route to the REST root (optional)
1414

1515
In the following example, you add a greeting resource to the REST API.
@@ -51,19 +51,26 @@ services:
5151
[[= include_file('code_samples/api/rest_api/config/services.yaml', 36, 42) =]]
5252
```
5353

54-
Having the REST controllers set as services enables using features such as the `InputDispatcher` service in the [Controller action](#controller-action).
54+
Having the REST controllers set as services enables using features such as
55+
56+
- TODO: `controller.service_arguments`??
57+
- TODO: `ibexa.api_platform.resource` tag is needed to have the route available in live doc (/api/ibexa/v2/doc#/App/api_greet_get)
5558

5659
### Controller action
5760

5861
A REST controller should:
5962

60-
- return a value object and have a `Generator` and `ValueObjectVisitor`s producing the XML or JSON output
61-
- extend `Ibexa\Rest\Server\Controller` to inherit utils methods and properties like `InputDispatcher` or `RequestParser`
63+
- return an object (passed automatically to a normaliser) or a `Response` (to customize it further)
64+
- TODO: extend `Ibexa\Rest\Server\Controller` to inherit utils methods and properties like `InputDispatcher` or `RequestParser`
6265

6366
``` php
64-
[[= include_file('code_samples/api/rest_api/src/Rest/Controller/DefaultController.php') =]]
67+
[[= include_file('code_samples/api/rest_api/src/Rest/Controller/DefaultController.php', 0, 14) =]]
68+
[[= include_file('code_samples/api/rest_api/src/Rest/Controller/DefaultController.php', 246) =]]
6569
```
6670

71+
<details>
72+
<summary>TODO</summary>
73+
6774
If the returned value was depending on a location, it could have been wrapped in a `CachedValue` to be cached by the reverse proxy (like Varnish) for future calls.
6875

6976
`CachedValue` is used in the following way:
@@ -75,52 +82,34 @@ return new CachedValue(
7582
);
7683
```
7784

78-
## Value and ValueObjectVisitor
79-
80-
``` php
81-
[[= include_file('code_samples/api/rest_api/src/Rest/Values/Greeting.php') =]]
82-
```
83-
84-
A `ValueObjectVisitor` must implement the `visit` method.
85+
</details>
8586

86-
| Argument | Description |
87-
|--------------|--------------------------------------------------------------------------------------------------------------------------------------------------------|
88-
| `$visitor` | The output visitor.<br/>Can be used to set custom response headers (`setHeader`), HTTP status code ( `setStatus`) |
89-
| `$generator` | The actual response generator. It provides you with a DOM-like API. |
90-
| `$data` | The visited data. The exact object that you returned from the controller.<br/>It can't have a type declaration because the method signature is shared. |
87+
## Value and Normalizer
9188

9289
``` php
93-
[[= include_file('code_samples/api/rest_api/src/Rest/ValueObjectVisitor/Greeting.php') =]]
90+
[[= include_file('code_samples/api/rest_api/src/Rest/Values/Greeting.php') =]]
9491
```
9592

96-
The `Values/Greeting` class is linked to its `ValueObjectVisitor` through the service tag.
97-
9893
``` yaml
9994
services:
10095
#…
10196
[[= include_file('code_samples/api/rest_api/config/services.yaml', 43, 48) =]]
10297
```
10398

104-
Here, the media type is `application/vnd.ibexa.api.Greeting` plus a format.
105-
To have a different vendor than the default, you could create a new `Output\Generator` or hard-code it in the `ValueObjectVisitor` like in the [`RestLocation` example](adding_custom_media_type.md#new-restlocation-valueobjectvisitor).
106-
107-
## InputParser
108-
109-
A REST resource could use route parameters to handle input, but this example illustrates the usage of an input parser.
110-
111-
For this example, the structure is a `GreetingInput` root node with two leaf nodes, `Salutation` and `Recipient`.
99+
A normalizer must implement the `supportsNormalization` and `normalize` methods.
112100

113101
``` php
114-
[[= include_file('code_samples/api/rest_api/src/Rest/InputParser/GreetingInput.php') =]]
102+
[[= include_file('code_samples/api/rest_api/src/Rest/Serializer/GreetingNormalizer.php') =]]
115103
```
116104

117-
Here, this `InputParser` directly returns the right value object.
118-
In other cases, it could return whatever object is needed to represent the input for the controller to perform its action, like arguments to use with a Repository service.
105+
## Input denormalizer
119106

120-
``` yaml
121-
services:
122-
#…
123-
[[= include_file('code_samples/api/rest_api/config/services.yaml', 48, 53) =]]
107+
A REST resource could use route parameters to handle input, but this example illustrates the usage of denormalized payload.
108+
109+
For this example, the structure is a `GreetingInput` root node with two leaf nodes, `salutation` and `recipient`.
110+
111+
``` php
112+
[[= include_file('code_samples/api/rest_api/src/Rest/Serializer/GreetingInputDenormalizer.php') =]]
124113
```
125114

126115
## Testing the new resource
@@ -138,43 +127,54 @@ curl https://api.example.com/api/ibexa/v2/greet --include --request POST \
138127
--header 'Accept: application/vnd.ibexa.api.Greeting+json';
139128
```
140129

141-
```
130+
```http
142131
HTTP/1.1 200 OK
143-
Content-Type: application/vnd.ibexa.api.greeting+xml
132+
Content-Type: application/vnd.ibexa.api.Greeting+xml
144133
145134
<?xml version="1.0" encoding="UTF-8"?>
146-
<Greeting media-type="application/vnd.ibexa.api.Greeting+xml" href="/api/ibexa/v2/greet">
135+
<Greeting>
147136
<Salutation>Hello</Salutation>
148137
<Recipient>World</Recipient>
149138
<Sentence>Hello World</Sentence>
150139
</Greeting>
151140
152141
HTTP/1.1 200 OK
153-
Content-Type: application/vnd.ibexa.api.greeting+xml
142+
Content-Type: application/vnd.ibexa.api.Greeting+xml
154143
155-
<?xml version="1.0" encoding="UTF-8"?>
156-
<Greeting media-type="application/vnd.ibexa.api.Greeting+xml" href="/api/ibexa/v2/greet">
157-
<Salutation>Good morning</Salutation>
158-
<Recipient>World</Recipient>
159-
<Sentence>Good morning World</Sentence>
144+
<?xml version="1.0"?>
145+
<Greeting>
146+
<Salutation>Good morning</Salutation>
147+
<Recipient>World</Recipient>
148+
<Sentence>Good morning World</Sentence>
160149
</Greeting>
161150
162151
HTTP/1.1 200 OK
163152
Content-Type: application/vnd.ibexa.api.greeting+json
164153
165154
{
166155
"Greeting": {
167-
"_media-type": "application\/vnd.ibexa.api.Greeting+json",
168-
"_href": "\/api\/ibexa\/v2\/greet",
169156
"Salutation": "Good day",
170157
"Recipient": "Earth",
171158
"Sentence": "Good day Earth"
172159
}
173160
}
174161
```
175162

163+
## Describe resource in OpenAPI schema
164+
165+
TODO
166+
167+
```php
168+
[[= include_file('code_samples/api/rest_api/src/Rest/Controller/DefaultController.php', 0, 246) =]]
169+
```
170+
171+
<details>
172+
<summary>
173+
176174
## Registering resources in REST root
177175

176+
</summary>
177+
178178
You can add the new resource to the [root resource](rest_api_usage.md#rest-root) through a configuration with the following pattern:
179179

180180
```yaml
@@ -211,3 +211,5 @@ The above example adds the following entry to the root XML output:
211211
```xml
212212
<greeting media-type="application/vnd.ibexa.api.Greeting+xml" href="/api/ibexa/v2/greet"/>
213213
```
214+
215+
</details>

0 commit comments

Comments
 (0)