README.md in avromatic-0.4.0 vs README.md in avromatic-0.5.0

- old
+ new

@@ -27,32 +27,43 @@ ### Configuration `Avromatic` supports the following configuration: -* schema_registry: An `AvroTurf::SchemaRegistry` object used to store Avro schemas - so that they can be referenced by id. Either `schema_registry` or - `registry_url` must be configured. See [Confluent Schema Registry](http://docs.confluent.io/2.0.1/schema-registry/docs/intro.html). -* registry_url: URL for the schema registry. The schema registry is used to store - Avro schemas so that they can be referenced by id. Either `schema_registry` or - `registry_url` must be configured. -* schema_store: The schema store is used to load Avro schemas from the filesystem. +#### Model Generation + +* **schema_store**: A schema store is required to load Avro schemas from the filesystem. It should be an object that responds to `find(name, namespace = nil)` and returns an `Avro::Schema` object. An `AvroTurf::SchemaStore` can be used. -* messaging: An `AvroTurf::Messaging` object to be shared by all generated models. + The `schema_store` is unnecessary if models are generated directly from + `Avro::Schema` objects. See [Models](#models). + +#### Using a Schema Registry/Messaging API + +The configuration options below are required when using a schema registry +(see [Confluent Schema Registry](http://docs.confluent.io/2.0.1/schema-registry/docs/intro.html)) +and the [Messaging API](#messaging-api). + +* **schema_registry**: An `AvroTurf::SchemaRegistry` object used to store Avro schemas + so that they can be referenced by id. Either `schema_registry` or + `registry_url` must be configured. +* **registry_url**: URL for the schema registry. Either `schema_registry` or + `registry_url` must be configured. +* **messaging**: An `AvroTurf::Messaging` object to be shared by all generated models. The `build_messaging!` method may be used to create a `Messaging` instance based on the other configuration values. -* logger: The logger to use for the schema registry client. +* **logger**: The logger to use for the schema registry client. * [Custom Types](#custom-types) -Example: +Example using a schema registry: ```ruby Avromatic.configure do |config| config.schema_store = AvroTurf::SchemaStore.new(path: 'avro/schemas') config.registry_url = Rails.configuration.x.avro_schema_registry_url config.build_messaging! +end ``` ### Models Models are defined based on an Avro schema for a record. @@ -134,62 +145,106 @@ inbound or outbound value is nil. If a custom type is registered for a record-type field, then any `to_avro` method/Proc should return a Hash with string keys for encoding using Avro. -#### Encode/Decode +### Encoding and Decoding -Models can be encoded using Avro leveraging a schema registry to encode a schema -id at the beginning of the value. +`Avromatic` provides two different interfaces for encoding the key (optional) +and value associated with a model. +#### Manually Managed Schemas + +The attributes for the value schema used to define a model can be encoded using: + ```ruby -model.avro_message_value +encoded_value = model.avro_raw_value ``` -If a model has an Avro schema for a key, then the key can also be encoded -prefixed with a schema id. +In order to decode this data, a copy of the value schema is required. +If a model also has an Avro schema for a key, then the key attributes can be +encoded using: + ```ruby -model.avro_message_key +encoded_key = model.avro_raw_key ``` -A model instance can be created from an Avro-encoded value and an Avro-encoded -optional key: +If attributes were encoded using the same schema(s) used to define a model, then +the data can be decoded to create a new model instance: ```ruby -MyTopic.deserialize(message_key, message_value) +MyModel.avro_raw_decode(key: encoded_key, value: encoded_value) ``` +If the attributes where encoded using a different version of the model's schemas, +then a new model instance can be created by also providing the schemas used to +encode the data: + +```ruby +MyModel.avro_raw_decode(key: encoded_key, + key_schema: writers_key_schema, + value: encoded_value, + value_schema: writers_value_schema) +``` + +#### Messaging API + +The other interface for encoding and decoding attributes uses the +`AvroTurf::Messaging` API. This interface leverages a schema registry and +prefixes the encoded data with an id to identify the schema. In this approach, +a schema registry is used to ensure that the correct schemas are available during +decoding. + +The attributes for the value schema can be encoded with a schema id prefix using: + +```ruby +message_value = model.avro_message_value +``` + +If a model has an Avro schema for a key, then those attributes can also be encoded +prefixed with a schema id: + +```ruby +message_key = model.avro_message_key +``` + +A model instance can be created from a key and value encoded in this manner: + +```ruby +MyTopic.avro_message_decode(message_key, message_value) +``` + Or just a value if only one schema is used: ```ruby -MyValue.deserialize(message_value) +MyValue.avro_message_decode(message_value) ``` -#### Decoder +#### Avromatric::Model::MessageDecoder -A stream of messages encoded from various models can be deserialized using -`Avromatic::Model::Decoder`. The decoder must be initialized with the list -of models to decode: +A stream of messages encoded from various models using the messaging approach +can be decoded using `Avromatic::Model::MessageDecoder`. The decoder must be +initialized with the list of models to decode: ```ruby -decoder = Avromatic::Model::Decoder.new(MyModel1, MyModel2) +decoder = Avromatic::Model::MessageDecoder.new(MyModel1, MyModel2) -decoder.decode(model1_key, model1_value) +decoder.decode(model1_messge_key, model1_message_value) # => instance of MyModel1 -decoder.decode(model2_value) +decoder.decode(model2_message_value) # => instance of MyModel2 ``` -#### Validations +### Validations The following validations are supported: - The size of the value for a fixed type field. - The value for an enum type field is in the declared set of values. - Presence of a value for required fields. -#### Unsupported/Future +### Unsupported/Future The following types/features are not supported for generated models: - Generic union fields: The special case of an optional field, the union of `:null` and another type, is supported.