Skip to content

Commit a7c3bcd

Browse files
committed
Add http decoder component doc page
1 parent 7ad19f3 commit a7c3bcd

File tree

2 files changed

+195
-2
lines changed

2 files changed

+195
-2
lines changed

Writerside/boson.tree

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,10 @@
5353
<toc-element topic="components.md">
5454
<toc-element topic="os-info.md" />
5555
<toc-element topic="cpu-info.md" />
56-
<toc-element topic="weak-types.md" />
57-
<toc-element topic="static-files.md" />
5856
<toc-element topic="globals-provider.md" />
57+
<toc-element topic="http-body-decoder.md" />
58+
<toc-element topic="http-static-provider.md" />
59+
<toc-element topic="weak-types.md" />
5960
</toc-element>
6061
<toc-element toc-title="Integrations">
6162
<toc-element topic="symfony-adapter.md"
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
# HTTP Body Decoder
2+
3+
<show-structure for="chapter" depth="2"/>
4+
5+
Provides the ability to decode the request body and obtain useful information
6+
from there based on the request information.
7+
8+
<warning>
9+
This component is not included by default in the <code>boson-php/runtime</code>
10+
and must be installed separately.
11+
</warning>
12+
13+
14+
## Installation
15+
16+
<tldr>
17+
<p>
18+
Via <a href="https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies">Composer</a>:
19+
</p>
20+
<p>
21+
<code lang="bash">composer require boson-php/http-body-decoder</code>
22+
</p>
23+
</tldr>
24+
25+
**Requirements:**
26+
27+
* `PHP ^8.4`
28+
29+
30+
## Usage
31+
32+
The component provides a flexible system for decoding HTTP request bodies with
33+
support for different content types.
34+
35+
### Basic Usage
36+
37+
The main entry point is the `BodyDecoderFactory` class, which automatically
38+
selects the appropriate decoder based on the request:
39+
40+
```php
41+
use Boson\Component\Http\Body\BodyDecoderFactory;
42+
use Boson\Component\Http\Body\FormUrlEncodedDecoder;
43+
use Boson\Component\Http\Body\MultipartFormDataDecoder;
44+
use Boson\Component\Http\Request;
45+
46+
// Create decoders factory
47+
$factory = new BodyDecoderFactory([
48+
// Decodes "application/x-www-form-urlencoded" requests
49+
new FormUrlEncodedDecoder(),
50+
// Decodes "multipart/form-data" requests
51+
new MultipartFormDataDecoder(),
52+
]);
53+
54+
// Decode request
55+
$decodedBody = $factory->decode( $bosonRequest );
56+
```
57+
58+
### Supported Decoders
59+
60+
#### Form URL Encoded
61+
62+
The `FormUrlEncodedDecoder` handles `application/x-www-form-urlencoded`
63+
content type:
64+
65+
```php
66+
use Boson\Component\Http\Body\FormUrlEncodedDecoder;
67+
use Boson\Component\Http\Request;
68+
69+
$decoder = new FormUrlEncodedDecoder();
70+
71+
$request = new Request(
72+
method: 'POST',
73+
headers: ['Content-Type' => 'application/x-www-form-urlencoded'],
74+
body: 'name=John&age=30'
75+
);
76+
77+
$decodedBody = $decoder->decode(new Request(
78+
method: 'POST',
79+
headers: ['Content-Type' => 'application/x-www-form-urlencoded'],
80+
body: 'name=John&age=30'
81+
));
82+
83+
//
84+
// Expected output:
85+
//
86+
// array:2 [
87+
// "name" => "John"
88+
// "age" => "30"
89+
// ]
90+
//
91+
```
92+
93+
#### Multipart Form Data
94+
95+
The `MultipartFormDataDecoder` handles `multipart/form-data` content type,
96+
including file uploads:
97+
98+
```php
99+
use Boson\Component\Http\Body\MultipartFormDataDecoder;
100+
use Boson\Component\Http\Request;
101+
102+
$decoder = new MultipartFormDataDecoder();
103+
104+
$decodedBody = $decoder->decode(new Request(
105+
method: 'POST',
106+
headers: [
107+
'Content-Type' => 'multipart/form-data;'
108+
. ' boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW'
109+
],
110+
// Note: The HTTP protocol uses \r\n delimiters
111+
body: str_replace(["\r\n", "\n"], "\r\n", <<<'BODY'
112+
------WebKitFormBoundary7MA4YWxkTrZu0gW
113+
Content-Disposition: form-data; name="name"
114+
115+
John
116+
------WebKitFormBoundary7MA4YWxkTrZu0gW
117+
Content-Disposition: form-data; name="file"; filename="test.txt"
118+
Content-Type: text/plain
119+
120+
Hello World
121+
------WebKitFormBoundary7MA4YWxkTrZu0gW--
122+
BODY),
123+
));
124+
125+
//
126+
// Expected output:
127+
//
128+
// array:2 [
129+
// "name" => "John"
130+
// "file" => "Hello World"
131+
// ]
132+
//
133+
```
134+
135+
### Creating Custom Decoders
136+
137+
You can create custom decoders by implementing
138+
the `SpecializedBodyDecoderInterface`:
139+
140+
<note>
141+
The <code>SpecializedBodyDecoderInterface</code> interface means that the
142+
decoder will respond to a specific specialized request type
143+
(see method <code>isDecodable()</code>).
144+
</note>
145+
146+
```php
147+
use Boson\Component\Http\Body\SpecializedBodyDecoderInterface;
148+
use Boson\Component\Http\Request;
149+
150+
class JsonBodyDecoder implements SpecializedBodyDecoderInterface
151+
{
152+
public function decode(RequestInterface $request): array
153+
{
154+
return (array) (\json_decode($request->body, true) ?? []);
155+
}
156+
157+
public function isDecodable(RequestInterface $request): bool
158+
{
159+
return $request->headers->first('content-type')
160+
=== 'application/json';
161+
}
162+
}
163+
164+
$factory = new BodyDecoderFactory([
165+
new JsonBodyDecoder(),
166+
// ... other decoders
167+
]);
168+
```
169+
170+
### Error Handling
171+
172+
The factory handles decoder errors gracefully:
173+
174+
```php
175+
use Boson\Component\Http\Body\BodyDecoderFactory;
176+
use Boson\Component\Http\Request;
177+
178+
$factory = new BodyDecoderFactory($decoders);
179+
180+
// If no decoder is suitable or decoding fails
181+
$decodedBody = $factory->decode(new Request(
182+
method: 'POST',
183+
headers: ['Content-Type' => 'unknown/type'],
184+
body: 'invalid data'
185+
));
186+
187+
//
188+
// Expected output:
189+
//
190+
// [] (empty array)
191+
//
192+
```

0 commit comments

Comments
 (0)