meritum/serialization
最新稳定版本:1.0.0
Composer 安装命令:
composer require meritum/serialization
包简介
Pluggable object serialization for the Meritum ecosystem with item, collection, and pagination support
README 文档
README
Pluggable object serialization with item, collection, and pagination support.
Requirements
- PHP 8.4+
georgeff\kernel^1.6
Installation
composer require meritum/serialization
Overview
The package is built around three concepts:
- Serializer — transforms a model into a plain array
- Resource — wraps a model (or iterable) with its serializer and optional metadata
- Formatter — accepts a resource, applies a format strategy, and returns a
JsonSerializableenvelope
The format strategy controls the output shape. Two strategies are provided out of the box, and you can supply your own by implementing StrategyInterface.
Serializers
Implement SerializerInterface to define how a model maps to an array:
use Meritum\Serialization\SerializerInterface; final class UserSerializer implements SerializerInterface { public function serialize(mixed $data): array { return [ 'id' => $data->id, 'name' => $data->name, 'email' => $data->email, ]; } }
To embed a related model, call the related serializer's serialize() directly. The formatter does not recurse — related data must be resolved to a plain array inside serialize():
final class PostSerializer implements SerializerInterface { public function serialize(mixed $data): array { return [ 'id' => $data->id, 'title' => $data->title, 'author' => new UserSerializer()->serialize($data->author), ]; } }
Formatter
Formatter is the entry point. Construct it with a StrategyInterface and call format() with an Item or Collection:
use Meritum\Serialization\Formatter; use Meritum\Serialization\Resource\Item; use Meritum\Serialization\Strategy\DataArrayStrategy; $formatter = new Formatter(new DataArrayStrategy()); $envelope = $formatter->format(new Item($user, new UserSerializer())); // $envelope implements JsonSerializable — pass it directly to any JSON response return new JsonResponse($envelope);
Item
Wrap a single model in an Item:
use Meritum\Serialization\Resource\Item; $item = new Item($user, new UserSerializer()); $envelope = $formatter->format($item);
With DataArrayStrategy (the default), the output is:
{
"data": {
"id": 1,
"name": "Mike",
"email": "mike@georgeff.co"
}
}
Collection
Wrap an iterable of models in a Collection. Any iterable is accepted, including generators:
use Meritum\Serialization\Resource\Collection; $collection = new Collection($users, new UserSerializer()); $envelope = $formatter->format($collection);
Output:
{
"data": [
{ "id": 1, "name": "Mike", "email": "mike@georgeff.co" },
{ "id": 2, "name": "Steve", "email": "steve@georgeff.co" }
]
}
Metadata
Both Item and Collection accept call-site metadata via addMeta(). Multiple calls chain fluently. The meta key is omitted from the output entirely when empty:
$item = (new Item($user, new UserSerializer())) ->addMeta('version', 2) ->addMeta('requestId', 'abc123'); $envelope = $formatter->format($item);
{
"data": { "id": 1, "name": "Mike", "email": "mike@georgeff.co" },
"meta": { "version": 2, "requestId": "abc123" }
}
Pagination
Cursor pagination
Implement CursorInterface and attach it to a Collection with setCursor():
use Meritum\Serialization\Pagination\CursorInterface; final class MyCursor implements CursorInterface { public function getPrevious(): ?string { ... } public function getNext(): ?string { ... } public function getPerPage(): int { ... } }
$collection = (new Collection($users, new UserSerializer())) ->setCursor($cursor); $envelope = $formatter->format($collection);
{
"limit": 25,
"previous": null,
"next": "eyJpZCI6MjZ9",
"data": [...]
}
Offset pagination
Implement PaginatorInterface and attach it with setPaginator():
use Meritum\Serialization\Pagination\PaginatorInterface; final class MyPaginator implements PaginatorInterface { public function getCurrentPage(): int { ... } public function getLastPage(): int { ... } public function getTotal(): int { ... } public function getCount(): int { ... } public function getPerPage(): int { ... } }
$collection = (new Collection($users, new UserSerializer())) ->setPaginator($paginator); $envelope = $formatter->format($collection);
{
"total": 100,
"count": 20,
"limit": 20,
"current": 2,
"last": 5,
"data": [...]
}
setCursor() and setPaginator() are mutually exclusive — setting one clears the other. Pagination keys always appear before data in the output.
A bridge package for meritum/database paginators will provide concrete implementations of both interfaces.
Output strategies
DataArrayStrategy (default)
Items are wrapped under a data key. Collections always include a data key. This is the default strategy registered by SerializationModule.
ArrayStrategy
Items are returned as a bare array with no data wrapper. Collections behave the same as DataArrayStrategy — the difference only applies to items.
use Meritum\Serialization\Formatter; use Meritum\Serialization\Strategy\ArrayStrategy; $formatter = new Formatter(new ArrayStrategy()); $envelope = $formatter->format(new Item($user, new UserSerializer())); // {"id": 1, "name": "Mike", "email": "mike@georgeff.co"}
Custom strategies
Implement StrategyInterface to take full control of the output format:
use Meritum\Serialization\EnvelopeInterface; use Meritum\Serialization\Envelope; use Meritum\Serialization\Resource\ItemInterface; use Meritum\Serialization\Resource\CollectionInterface; use Meritum\Serialization\Strategy\StrategyInterface; final class MyStrategy implements StrategyInterface { public function item(ItemInterface $item): EnvelopeInterface { $data = ['result' => $item->getSerializer()->serialize($item->getData())]; if ([] !== $item->getMeta()) { $data['meta'] = $item->getMeta(); } return new Envelope($data); } public function collection(CollectionInterface $collection): EnvelopeInterface { $data = $collection->getPagination(); $data['results'] = []; foreach ($collection->getData() as $model) { $data['results'][] = $collection->getSerializer()->serialize($model); } if ([] !== $collection->getMeta()) { $data['meta'] = $collection->getMeta(); } return new Envelope($data); } }
Kernel integration
SerializationModule registers FormatterInterface in the kernel container. It uses DataArrayStrategy by default. To swap in a custom strategy, register StrategyInterface before booting:
use Meritum\Serialization\SerializationModule; use Meritum\Serialization\Strategy\StrategyInterface; $kernel->define(StrategyInterface::class, fn () => new MyStrategy())->share(); $kernel->addModule(new SerializationModule()); $kernel->boot(); $formatter = $kernel->getContainer()->get(FormatterInterface::class);
To run multiple formatters with different strategies in the same application, bypass the module and define them manually:
use Meritum\Serialization\Formatter; use Meritum\Serialization\Strategy\ArrayStrategy; use Meritum\Serialization\Strategy\DataArrayStrategy; $kernel->define('formatter.default', fn () => new Formatter(new DataArrayStrategy()))->share(); $kernel->define('formatter.bare', fn () => new Formatter(new ArrayStrategy()))->share();
License
MIT
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 2
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-06-11