1- # KaririCode\ Serializer
1+ # KaririCode Serializer
22
3- ** Multi-format serialization for PHP 8.4+ — JSON, XML, CSV, QueryString encoders, zero dependencies. **
3+ < div align = " center " >
44
5- [ ![ PHP Version] ( https://img.shields.io/badge/php-%3E%3D8.4-blue )] ( https://www.php.net/ )
6- [ ![ License] ( https://img.shields.io/badge/license-MIT-green )] ( LICENSE )
7- [ ![ ARFA] ( https://img.shields.io/badge/ARFA-1.3-orange )] ( )
8- [ ![ Encoders] ( https://img.shields.io/badge/encoders-4-brightgreen )] ( )
5+ [ ![ PHP 8.4+] ( https://img.shields.io/badge/PHP-8.4%2B-777BB4?logo=php&logoColor=white )] ( https://www.php.net/ )
6+ [ ![ CI] ( https://github.com/KaririCode-Framework/kariricode-serializer/actions/workflows/ci.yml/badge.svg )] ( https://github.com/KaririCode-Framework/kariricode-serializer/actions/workflows/ci.yml )
7+ [ ![ License: MIT] ( https://img.shields.io/badge/License-MIT-22c55e.svg )] ( LICENSE )
8+ [ ![ PHPStan Level 9] ( https://img.shields.io/badge/PHPStan-Level%209-4F46E5 )] ( https://phpstan.org/ )
9+ [ ![ Tests] ( https://img.shields.io/badge/Tests-100%25_pass-22c55e )] ( tests/ )
10+ [ ![ Encoders] ( https://img.shields.io/badge/Encoders-4-22c55e )] ( https://kariricode.org )
11+ [ ![ Zero Runtime Deps] ( https://img.shields.io/badge/Runtime%20Deps-0-22c55e )] ( composer.json )
12+ [ ![ ARFA] ( https://img.shields.io/badge/ARFA-1.3-orange )] ( https://kariricode.org )
13+ [ ![ KaririCode Framework] ( https://img.shields.io/badge/KaririCode-Framework-orange )] ( https://kariricode.org )
914
10- Part of the [ KaririCode Framework ] ( https://github.com/kariricode ) processing ecosystem.
15+ ** Multi-format serialization for PHP 8.4+ — JSON, XML, CSV, QueryString, zero dependencies. **
1116
12- ## Why KaririCode\Serializer
17+ [ Installation ] ( #installation ) · [ Quick Start ] ( #quick-start ) · [ Attribute-Driven ] ( #attribute-driven-dto-serialization ) · [ All Encoders ] ( #all-4-encoders ) · [ Architecture ] ( #architecture )
1318
14- - ** 4 built-in encoders** : JSON, XML, CSV, QueryString — extensible via Encoder contract
15- - ** Attribute-driven** : ` #[Serialize] ` with name mapping, groups, and ignore support
16- - ** Serialization groups** : control field visibility per consumer (public, admin, internal)
17- - ** Zero external dependencies** — pure PHP 8.4+ built-ins (json, SimpleXML, fputcsv)
18- - ** Same architecture** as Validator, Sanitizer, Transformer, Normalizer, Mapper
19+ </div >
20+
21+ ---
22+
23+ ## The Problem
24+
25+ Multi-format serialization for PHP always pulls in heavy dependencies or loses the data contract:
26+
27+ ``` php
28+ // symfony/serializer: 7+ packages, complex config, annotation magic
29+ // league/fractal: transformer boilerplate, no attribute support
30+ // json_encode/decode alone: no groups, no field renaming, no XML/CSV
31+
32+ // Switching from JSON to XML means rewriting your serialization layer entirely.
33+ ```
34+
35+ ## The Solution
36+
37+ ``` php
38+ use KaririCode\Serializer\Provider\SerializerServiceProvider;
39+
40+ $engine = (new SerializerServiceProvider())->createEngine();
41+
42+ // One API, four formats — swap format string to change output
43+ $json = $engine->serialize(['name' => 'Walmir', 'age' => 30], 'json');
44+ $xml = $engine->serialize(['name' => 'Walmir', 'age' => 30], 'xml', ['root' => 'user']);
45+ $csv = $engine->serialize([['name' => 'Walmir', 'age' => 30]], 'csv');
46+ $qs = $engine->serialize(['name' => 'Walmir', 'age' => 30], 'query_string');
47+
48+ // RFC 8259 (JSON) · RFC 4180 (CSV) · RFC 3986 (URL) — built-in compliance
49+ ```
50+
51+ ---
52+
53+ ## Requirements
54+
55+ | Requirement | Version |
56+ | ---| ---|
57+ | PHP | 8.4 or higher |
58+ | ext-simplexml | Built-in (required for XML) |
59+ | kariricode/property-inspector | ^2.0 |
60+
61+ ---
1962
2063## Installation
2164
2265``` bash
2366composer require kariricode/serializer
2467```
2568
69+ ---
70+
2671## Quick Start
2772
2873``` php
74+ <?php
75+
76+ require_once __DIR__ . '/vendor/autoload.php';
77+
2978use KaririCode\Serializer\Provider\SerializerServiceProvider;
3079
3180$engine = (new SerializerServiceProvider())->createEngine();
@@ -43,6 +92,8 @@ $result = $engine->serialize(['name' => 'Walmir'], 'xml', ['root' => 'user']);
4392// <user ><name >Walmir</name ></user >
4493```
4594
95+ ---
96+
4697## Attribute-Driven DTO Serialization
4798
4899``` php
@@ -60,7 +111,7 @@ class UserDto
60111 public string $passwordHash = '...';
61112}
62113
63- $provider = new SerializerServiceProvider();
114+ $provider = new SerializerServiceProvider();
64115$serializer = $provider->createAttributeSerializer();
65116
66117// Serialize to JSON (public group)
@@ -75,15 +126,19 @@ $json = $serializer->serialize(new UserDto(), 'json', ['admin']);
75126$dto = $serializer->deserialize('{"name":"Walmir"}', UserDto::class, 'json');
76127```
77128
129+ ---
130+
78131## All 4 Encoders
79132
80133| Format | Encoder | MIME Type | PHP Functions |
81- | -------- | --------- | ----------- | ------------ ---|
134+ | ---| ---| ---| ---|
82135| ` json ` | JsonEncoder | application/json | json_encode/decode with JSON_THROW_ON_ERROR |
83136| ` xml ` | XmlEncoder | application/xml | SimpleXMLElement + DOMDocument |
84137| ` csv ` | CsvEncoder | text/csv | fputcsv/str_getcsv via php://temp |
85138| ` query_string ` | QueryStringEncoder | application/x-www-form-urlencoded | http_build_query/parse_str |
86139
140+ ---
141+
87142## Adding Custom Encoders
88143
89144``` php
@@ -101,25 +156,27 @@ $registry = $provider->createRegistry();
101156$registry->register(new YamlEncoder());
102157```
103158
159+ ---
160+
104161## Engine API (Programmatic)
105162
106163``` php
107164$engine = (new SerializerServiceProvider())->createEngine();
108165
109- // Serialize array to JSON
110166$result = $engine->serialize(['name' => 'Walmir', 'age' => 30], 'json');
111- $result->getPayload(); // '{"name":"Walmir","age":30}'
112- $result->getFormat(); // 'json'
113- $result->getPayloadSize(); // byte count
167+ $result->getPayload(); // '{"name":"Walmir","age":30}'
168+ $result->getFormat(); // 'json'
169+ $result->getPayloadSize(); // byte count
114170
115- // Deserialize JSON to array
116171$data = $engine->deserialize('{"name":"Walmir"}', 'json');
117172// ['name' => 'Walmir']
118173
119174// CSV with custom separator
120175$result = $engine->serialize([['a' => 1, 'b' => 2]], 'csv', ['separator' => ';']);
121176```
122177
178+ ---
179+
123180## Ecosystem Position
124181
125182```
@@ -128,28 +185,84 @@ Infra Pipeline: Object ↔ Normalizer ↔ Array ↔ ★ Serializer ★ ↔ Str
128185Cross-Layer: Request DTO ↔ Mapper ↔ Domain Entity ↔ Mapper ↔ Response DTO
129186```
130187
131- The Serializer converts ** already-normalized arrays** into wire format strings for transport.
188+ The Serializer converts ** already-normalized arrays** into wire-format strings for transport. It is the last step in the infrastructure pipeline before the payload leaves the application.
189+
190+ ---
132191
133192## Architecture
134193
135- - ARFA 1.3 compliant (immutable context, reactive pipeline, observability events)
136- - Quality Directive V4.0 (all encoders ` final readonly ` , zero dependencies)
137- - RFC 8259 (JSON), RFC 4180 (CSV), RFC 3986 (URL encoding)
138- - See [ docs/] ( docs/ ) for 3 ADRs, 2 SPECs, and compliance report
194+ ### Source layout
195+
196+ ```
197+ src/
198+ ├── Attribute/ Serialize — name, groups, ignore annotation
199+ ├── Configuration/ SerializerConfiguration (immutable)
200+ ├── Contract/ Encoder · SerializationContext · SerializerEngine · EncoderRegistry
201+ ├── Core/ SerializerEngine · SerializationContextImpl · InMemoryEncoderRegistry
202+ ├── Encoder/ JsonEncoder · XmlEncoder · CsvEncoder · QueryStringEncoder
203+ ├── Exception/ SerializationException
204+ └── Provider/ SerializerServiceProvider — factory for engine & attribute serializer
205+ ```
206+
207+ ### Key design decisions
208+
209+ | Decision | Rationale | ADR |
210+ | ---| ---| ---|
211+ | Format-agnostic engine | Swap format string — no code changes | [ ADR-001] ( docs/adr/ADR-001-format-agnostic-engine.md ) |
212+ | Serialization groups | Field visibility per consumer without multiple DTOs | [ ADR-002] ( docs/adr/ADR-002-serialization-groups.md ) |
213+ | RFC compliance | JSON 8259, CSV 4180, URL 3986 | [ ADR-003] ( docs/adr/ADR-003-rfc-compliance.md ) |
214+ | Property Inspector integration | Attribute scanning delegated to kariricode/property-inspector | [ ADR-004] ( docs/adr/ADR-004-attribute-handler-via-property-inspector.md ) |
215+ | Zero encoder dependencies | All 4 encoders use only PHP built-ins | [ ADR-005] ( docs/adr/ADR-005-zero-dependency-encoders.md ) |
216+
217+ ### Specifications
218+
219+ | Spec | Covers |
220+ | ---| ---|
221+ | [ SPEC-001] ( docs/spec/SPEC-001-encoder-contract.md ) | Encoder interface and registration |
222+ | [ SPEC-002] ( docs/spec/SPEC-002-attribute-model.md ) | ` #[Serialize] ` groups and field mapping |
223+ | [ SPEC-003] ( docs/spec/SPEC-003-serialize-attribute-handler.md ) | ` SerializeAttributeHandler ` contract and invariants |
139224
140- ## Metrics
225+ ---
226+
227+ ## Project Stats
141228
142229| Metric | Value |
143- | -------- | ---- ---|
144- | Source files | 19 |
145- | Source lines | 662 |
146- | Test files | 8 |
147- | Test lines | 396 |
148- | Total | ** 27 files / 1,058 lines ** |
230+ | ---| ---|
231+ | PHP source files | 19 |
232+ | Source lines | ~ 720 |
233+ | Test files | 13 |
234+ | Test lines | ~ 700 |
235+ | External runtime dependencies | 1 (kariricode/property-inspector) |
149236| Encoder classes | 4 |
150237| Supported formats | JSON, XML, CSV, QueryString |
151- | External dependencies | ** 0** |
238+ | PHPStan level | 9 |
239+ | PHP version | 8.4+ |
240+ | ARFA compliance | 1.3 |
241+
242+ ---
243+
244+ ## Contributing
245+
246+ ``` bash
247+ git clone https://github.com/KaririCode-Framework/kariricode-serializer.git
248+ cd kariricode-serializer
249+ composer install
250+ kcode init
251+ kcode quality # Must pass before opening a PR
252+ ```
253+
254+ ---
152255
153256## License
154257
155- MIT © Walmir Silva — KaririCode Framework
258+ [ MIT License] ( LICENSE ) © [ Walmir Silva] ( mailto:community@kariricode.org )
259+
260+ ---
261+
262+ <div align =" center " >
263+
264+ Part of the ** [ KaririCode Framework] ( https://kariricode.org ) ** ecosystem.
265+
266+ [ kariricode.org] ( https://kariricode.org ) · [ GitHub] ( https://github.com/KaririCode-Framework/kariricode-serializer ) · [ Packagist] ( https://packagist.org/packages/kariricode/serializer ) · [ Issues] ( https://github.com/KaririCode-Framework/kariricode-serializer/issues )
267+
268+ </div >
0 commit comments