flix-tech/avro-serde-php
PHP library for serializing/deserializing Apache Avro with Schema Registry support. Built for Kafka-style messaging, it handles Avro binary encoding, schema resolution, and compatibility, providing a straightforward SerDe layer you can use in your own producers/consumers.
Installation:
composer require flix-tech/avro-serde-php
For Symfony projects, also install the serializer bridge:
composer require flix-tech/avro-serde-php-symfony
First Use Case:
Define an Avro schema (e.g., user.avsc):
{
"type": "record",
"name": "User",
"fields": [
{"name": "id", "type": "int"},
{"name": "name", "type": "string"}
]
}
Load and serialize:
use FlixTech\AvroSerde\AvroSerializer;
$serializer = new AvroSerializer();
$schema = $serializer->loadSchemaFromFile(__DIR__.'/user.avsc');
$data = ['id' => 1, 'name' => 'John Doe'];
$binary = $serializer->serialize($data, $schema);
Symfony Integration:
Register the serializer in config/services.yaml:
services:
FlixTech\AvroSerde\Symfony\AvroEncoder:
arguments:
- '@avro_serializer'
Use in controllers:
use Symfony\Component\HttpFoundation\JsonResponse;
use FlixTech\AvroSerde\Symfony\AvroEncoder;
public function index(AvroEncoder $encoder): JsonResponse
{
$data = ['id' => 1, 'name' => 'John Doe'];
$binary = $encoder->encode($data, $schema);
return new JsonResponse(['avro' => base64_encode($binary)]);
}
config/avro/schemas/) and load them dynamically:
$serializer->loadSchemaFromFile('path/to/schema.avsc');
$serializer->setSchemaCache(new \Symfony\Component\Cache\Adapter\FilesystemAdapter());
record and array types for nested structures:
{
"type": "record",
"name": "Order",
"fields": [
{"name": "user", "type": ["User", {"default": null}]},
{"name": "items", "type": {"type": "array", "items": "string"}}
]
}
{"type": ["null", "string"]}
AvroEncoder/AvroDecoder in Symfony’s JsonResponse/JsonRequest:
$request->getContent(); // Binary Avro data
$decoded = $decoder->decode($request->getContent(), $schema);
# config/packages/serializer.yaml
FlixTech\AvroSerde\Symfony\AvroEncoder:
groups: ['avro']
AvroSerializer::serializeToStream():
$stream = $serializer->serializeToStream($data, $schema);
file_put_contents('output.avro', $stream);
int vs. long). Use strictMode: true in config to fail fast:
$serializer->setStrictMode(true);
bytes) are serialized as raw bytes. Encode for transport:
base64_encode($serializer->serialize($data, $schema));
# config/packages/serializer.yaml
Symfony\Component\Serializer\Normalizer\ObjectNormalizer:
enable_max_depth: false
AvroSerializer::validateSchema() to pre-check schemas:
if (!$serializer->validateSchema($schemaJson)) {
throw new \RuntimeException('Invalid schema');
}
$decoded = $serializer->deserialize($binaryData, $schema);
FlixTech\AvroSerde\Type\TypeInterface for custom Avro types (e.g., UUIDs):
class UuidType implements TypeInterface {
public function serialize($value, Schema $schema): string {}
public function deserialize(string $data, Schema $schema): ?string {}
}
$dispatcher->addListener(
AvroEvents::PRE_SERIALIZE,
function ($event) { /* Modify data */ }
);
$serializer->compileSchema($schemaJson); // One-time cost
serializeToStream() for large datasets to avoid memory spikes.How can I help you explore Laravel packages today?