{"id":15405127,"url":"https://github.com/strech/avrora","last_synced_at":"2025-05-15T16:03:14.128Z","repository":{"id":35010797,"uuid":"195590809","full_name":"Strech/avrora","owner":"Strech","description":"A convenient Elixir library to work with Avro messages, schemas and Confluent® Schema Registry","archived":false,"fork":false,"pushed_at":"2025-04-01T10:21:51.000Z","size":701,"stargazers_count":101,"open_issues_count":16,"forks_count":35,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-07T21:13:39.291Z","etag":null,"topics":["avro","avro-schema","confluent","elixir","kafka","schema-registry"],"latest_commit_sha":null,"homepage":"https://hexdocs.pm/avrora","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Strech.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":["Strech"],"patreon":null,"open_collective":null,"ko_fi":"strech","tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":["https://paypal.me/onistrech/eur5.0"]}},"created_at":"2019-07-06T23:18:34.000Z","updated_at":"2025-04-01T10:21:55.000Z","dependencies_parsed_at":"2023-01-15T11:57:18.267Z","dependency_job_id":"8c74b249-d7eb-4f8f-a594-ed70ae0c4621","html_url":"https://github.com/Strech/avrora","commit_stats":{"total_commits":197,"total_committers":20,"mean_commits":9.85,"dds":"0.10659898477157359","last_synced_commit":"a2df4d8f177dacc7be24aa3e6bc76b52c3f114a9"},"previous_names":[],"tags_count":45,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Strech%2Favrora","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Strech%2Favrora/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Strech%2Favrora/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Strech%2Favrora/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Strech","download_url":"https://codeload.github.com/Strech/avrora/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254374400,"owners_count":22060609,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["avro","avro-schema","confluent","elixir","kafka","schema-registry"],"created_at":"2024-10-01T16:15:08.118Z","updated_at":"2025-05-15T16:03:14.103Z","avatar_url":"https://github.com/Strech.png","language":"Elixir","funding_links":["https://github.com/sponsors/Strech","https://ko-fi.com/strech","https://paypal.me/onistrech/eur5.0","https://www.paypal.com/paypalme/onistrech/eur5.0","https://ko-fi.com/W7W8367XJ"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\" class=\"gfm\"\u003e\n    \u003cimg id=\"avroraLogo\" width=200 src=\"/assets/logo.png\"/\u003e\n    \u003ch1 align=\"center\"\u003eAvrora\u003c/h1\u003e\n\u003c/p\u003e\n\n\u003cspan class=\"nodoc\"\u003e\n\n[![Hex pm](https://img.shields.io/hexpm/v/avrora.svg?style=for-the-badge)](https://hex.pm/packages/avrora)\n[![Hex Docs](https://img.shields.io/badge/api-docs-blue.svg?style=for-the-badge)](https://hexdocs.pm/avrora)\n\n\u003c/span\u003e\n\n[v0.10]: https://github.com/Strech/avrora/releases/tag/v0.10.0\n[v0.12]: https://github.com/Strech/avrora/releases/tag/v0.12.0\n[v0.13]: https://github.com/Strech/avrora/releases/tag/v0.13.0\n[v0.14]: https://github.com/Strech/avrora/releases/tag/v0.14.0\n[v0.15]: https://github.com/Strech/avrora/releases/tag/v0.15.0\n[v0.16]: https://github.com/Strech/avrora/releases/tag/v0.16.0\n[v0.17]: https://github.com/Strech/avrora/releases/tag/v0.17.0\n[v0.18]: https://github.com/Strech/avrora/releases/tag/v0.18.0\n[v0.22]: https://github.com/Strech/avrora/releases/tag/v0.22.0\n[v0.23]: https://github.com/Strech/avrora/releases/tag/v0.23.0\n[v0.24]: https://github.com/Strech/avrora/releases/tag/v0.24.0\n[v0.25]: https://github.com/Strech/avrora/releases/tag/v0.25.0\n[v0.26]: https://github.com/Strech/avrora/releases/tag/v0.26.0\n[v0.28]: https://github.com/Strech/avrora/releases/tag/v0.28.0\n[v0.30]: https://github.com/Strech/avrora/releases/tag/v0.30.0\n[1]: https://avro.apache.org/\n[2]: https://www.confluent.io/confluent-schema-registry\n[3]: https://docs.confluent.io/current/schema-registry/serializer-formatter.html#wire-format\n[4]: https://avro.apache.org/docs/1.8.1/spec.html#Object+Container+Files\n[5]: https://docs.confluent.io/current/schema-registry/serdes-develop/index.html#referenced-schemas\n[6]: https://github.com/Strech/avrora/wiki/Inter-Schema-references\n[7]: https://github.com/dasch/avro_turf\n[8]: https://www.confluent.io/blog/multiple-event-types-in-the-same-kafka-topic/#avro-unions-with-schema-references\n[9]: https://github.com/Strech/avrora/wiki/Schema-name-resolution\n[10]: https://github.com/Strech/avrora/pull/70\n[11]: https://github.com/klarna/erlavro#decoder-hooks\n[12]: https://www.erlang.org/docs/26/man/ssl#type-client_cacerts\n[13]: https://www.erlang.org/docs/26/man/ssl#type-client_option\n\n# Getting Started\n\nThis Elixir library supports convenient encoding and decoding of [Avro][1] messages.\n\nIt can read the Avro schema from local files or the [Confluent® Schema Registry][2],\ncaching data in memory for performance.\n\nIt supports reading and writing data Kafka [wire format][3] prefix and from [Object Container Files][4]\nformats. Along with [Confluent® Schema References][5] it has [Inter-Schema references][6] feature for\nolder Schema Registry versions.\n\nMany thanks to the [AvroTurf][7] Ruby gem for the initial inspiration :blue_heart:\n\n---\n\n#### If you like the project and want to support me on my sleepless nights, you can\n\n[![Support via PayPal](https://cdn.rawgit.com/twolfson/paypal-github-button/1.0.0/dist/button.svg)](https://www.paypal.com/paypalme/onistrech/eur5.0)\n[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/W7W8367XJ)\n\n## Add Avrora to your project\n\nAdd Avrora to `mix.exs` as a dependency\n\n```elixir\ndef deps do\n  [\n    {:avrora, \"~\u003e 0.30\"}\n  ]\nend\n```\n\n## Configuration\n\n:beginner: It's recommended to configure private Avrora client\u003csup\u003e[v0.17]\u003c/sup\u003e to avoid\nrisk of conflicts with other dependencies which might use shared `Avrora` client.\n\nDon't worry if you already using the shared client because migration to the private is a\nmatter of copy-paste.\n\n### Private client\n\nCreate your private Avrora client module\n\n```elixir\ndefmodule MyClient do\n  use Avrora.Client,\n    otp_app: :my_application,\n    schemas_path: \"./priv/schemas\",\n    registry_url: \"http://localhost:8081\",\n    registry_auth: {:basic, [\"username\", \"password\"]},\n    registry_user_agent: \"Avrora/0.30.0 Elixir\",\n    registry_ssl_opts: [verify: :verify_none]\n    registry_ssl_cacerts: File.read!(\"./priv/trusted.der\"),\n    registry_ssl_cacert_path: \"./priv/trusted.crt\",\n    registry_schemas_autoreg: false,\n    convert_null_values: false,\n    convert_map_to_proplist: false,\n    names_cache_ttl: :timer.minutes(5),\n    decoder_hook: \u0026MyClient.decoder_hook/4\nend\n```\n\nplease check the section below :point_down: for detailed explanation of each configuration option.\n\n### Shared client\n\nConfigure the `Avrora` shared client in `config/config.exs`\n\n```elixir\nconfig :avrora,\n  otp_app: :my_application, # optional, if you want to use it as a root folder for `schemas_path`\n  schemas_path: \"./priv/schemas\",\n  registry_url: \"http://localhost:8081\",\n  registry_auth: {:basic, [\"username\", \"password\"]}, # optional\n  registry_user_agent: \"Avrora/0.30.0 Elixir\", # optional: if you want to return previous behaviour, set it to `nil`\n  registry_ssl_opts: [verify: :verify_none], # optional: if you want to set any available SSL options, overwriting rest\n  registry_ssl_cacerts: File.read!(\"./priv/trusted.der\"), # optional: if you have DER-encoded certificate\n  registry_ssl_cacert_path: \"./priv/trusted.crt\", # optional: if you have PEM-encoded certificate file\n  registry_schemas_autoreg: false, # optional: if you want manually register schemas\n  convert_null_values: false, # optional: if you want to keep decoded `:null` values as is\n  convert_map_to_proplist: false, # optional: if you want to restore the old behavior for decoding map-type\n  names_cache_ttl: :timer.minutes(5), # optional: if you want periodic disk reads\n  decoder_hook: \u0026MyClient.decoder_hook/4 # optional: if you want to amend the data/result\n```\n\n- `otp_app`\u003csup\u003e[v0.22]\u003c/sup\u003e - Name of the OTP application to use for runtime configuration via env, default `nil`\n- `schemas_path` - Base path for locally stored schema files, default `./priv/schemas`\n- `registry_url` - URL for the Schema Registry, default `nil`\n- `registry_auth` – Credentials to authenticate in the Schema Registry, default `nil`\n- `registry_user_agent`\u003csup\u003e[v0.25]\u003c/sup\u003e - HTTP `User-Agent` header for Schema Registry requests, default `Avrora/\u003cversion\u003e Elixir`\n- `registry_ssl_opts`\u003csup\u003e[v0.30]\u003c/sup\u003e - Arbitrary [SSL client options][13] in Erlang format (take precedence over other SSL options), default `nil`\n- `registry_ssl_cacerts`\u003csup\u003e[v0.28]\u003c/sup\u003e - DER-encoded certificates, but [without combined support][12], default `nil`\n- `registry_ssl_cacert_path`\u003csup\u003e[v0.28]\u003c/sup\u003e - Path to a file containing PEM-encoded CA certificates, default `nil`\n- `registry_schemas_autoreg`\u003csup\u003e[v0.13]\u003c/sup\u003e - Flag for automatic schemas registration in the Schema Registry, default `true`\n- `convert_null_values`\u003csup\u003e[v0.14]\u003c/sup\u003e - Flag for automatic conversion of decoded `:null` values into `nil`, default `true`\n- `convert_map_to_proplist`\u003csup\u003e[v0.15]\u003c/sup\u003e restore old behaviour and confiugre decoding map-type to proplist, default `false`\n- `names_cache_ttl`\u003csup\u003e[v0.10]\u003c/sup\u003e - Time in ms to cache schemas by name in memory, default `:infinity`\n- `decoder_hook`\u003csup\u003e[v0.24]\u003c/sup\u003e - Function with arity 4 to amend data or result, default `fn _, _, data, fun -\u003e fun.(data) end`\n\nSet `names_cache_ttl` to `:infinity` will cache forever (no more disk reads will\nhappen). This is safe when schemas resolved in the Schema Registry by\nnumeric id or **versioned** name, as it is unique. If you need to reload schema\nfrom the disk periodically, TTL different from `:infinity` ensures that.\n\nIf the schema resolved by name it will be always overwritten with the latest\nschema received from Schema Registry.\u003csup\u003e[v0.10]\u003c/sup\u003e\n\nCustom [decoder hook][11] will be first in the call-chain, after it's done Avrora\nwill use the result in its own decoder hook.\u003csup\u003e[v0.24]\u003c/sup\u003e\n\n:bulb: Disable schemas auto-registration if you want to avoid storing schemas\nand manually control registration process. Also it's recommended to turn off auto-registration\nwhen schemas containing [Confluent Schema References][8].\u003csup\u003e[v0.14]\u003c/sup\u003e\n\n:bulb: When you use releases and especially Umbrella apps with different clients it's\nrecommended to set `otp_app` which will point to your OTP applications. This will allow you\nto have a per-client runtime resolution for all configuration options (i.e. `schemas_path`)\nwith a fallback to staticly defined in a client itself.\u003csup\u003e[v0.23]\u003c/sup\u003e\n\n:bulb: If both `registry_ssl_cacerts` and `registry_ssl_cacert_path` given, then\n`registry_ssl_cacerts` has a priority.\n\n## Start cache process\n\nAvrora uses an in-memory cache to speed up schema lookup.\n\n### Private client\n\nAfter you've created your [private Avrora client](#private-client),\nadd it to your supervision tree\n\n```elixir\nchildren = [\n  MyClient\n]\n\nSupervisor.start_link(children, strategy: :one_for_one)\n```\n\nor start the process manually\n\n```elixir\n{:ok, pid} = MyClient.start_link()\n```\n\n### Shared client\n\nAdd shared `Avrora` module to your supervision tree\n\n```elixir\nchildren = [\n  Avrora\n]\n\nSupervisor.start_link(children, strategy: :one_for_one)\n```\n\nor start the process manually\n\n```elixir\n{:ok, pid} = Avrora.start_link()\n```\n\n## Usage\n\n:beginner: All the examples below (including [Schemas registration](#schemas-registration))\nwill use `Avrora` shared client, but if you are using private client,\njust replace `Avrora` with your client module name.\n\nThe primary way to use the library is via the `Avrora.encode/2` and\n`Avrora.decode/2` functions. These functions load the Avro schema for you.\n\nIf `registry_url` defined, it enables Schema Registry storage. If the schema\nfile found locally but not in the registry, either fuction will register the schema.\n\nThese examples assume you have a `Payment` schema stored in the file\n`priv/schemas/io/acme/Payment.avsc`\n\n```json\n{\n  \"type\": \"record\",\n  \"name\": \"Payment\",\n  \"namespace\": \"io.acme\",\n  \"fields\": [\n    {\n      \"name\": \"id\",\n      \"type\": \"string\"\n    },\n    {\n      \"name\": \"amount\",\n      \"type\": \"double\"\n    }\n  ]\n}\n```\n\nWhen running interactively, first make sure the cache started\n\n```elixir\n{:ok, pid} = Avrora.start_link()\n```\n\n### encode/2\n\nTo encode a `Payment` message:\n\n```elixir\n{:ok, pid} = Avrora.start_link()\nmessage = %{\"id\" =\u003e \"tx-1\", \"amount\" =\u003e 15.99}\n\n{:ok, encoded} = Avrora.encode(message, schema_name: \"io.acme.Payment\")\n\u003c\u003c79, 98, 106, 1, 3, 204, 2, 20, 97, 118, 114, 111, 46, 99, 111, 100, 101, 99,\n  8, 110, 117, 108, 108, 22, 97, 118, 114, 111, 46, 115, 99, 104, 101, 109, 97,\n  144, 2, 123, 34, 110, 97, 109, 101, 115, 112, 97, 99, 101, 34, 58, 34, 105,\n  111, 46, 99, 111, 110, 102, 108, 117, 101, 110, 116, 34, 44, 34, 110, 97, 109,\n  101, 34, 58, 34, 80, 97, 121, 109, 101, 110, 116, 34, 44, 34, 116, 121, 112,\n  101, 34, 58, 34, 114, 101, 99, 111, 114, 100, 34, 44, 34, 102, 105, 101, 108,\n  100, 115, 34, 58, 91, 123, 34, 110, 97, 109, 101, 34, 58, 34, 105, 100, 34,\n  44, 34, 116, 121, 112, 101, 34, 58, 34, 115, 116, 114, 105, 110, 103, 34, 125,\n  44, 123, 34, 110, 97, 109, 101, 34, 58, 34, 97, 109, 111, 117, 110, 116, 34,\n  44, 34, 116, 121, 112, 101, 34, 58, 34, 100, 111, 117, 98, 108, 101, 34, 125,\n  93, 125, 0, 138, 124, 66, 49, 157, 51, 242, 3, 33, 52, 161, 147, 221, 174,\n  114, 48, 2, 26, 8, 116, 120, 45, 49, 123, 20, 174, 71, 225, 250, 47, 64, 138,\n  124, 66, 49, 157, 51, 242, 3, 33, 52, 161, 147, 221, 174, 114, 48\u003e\u003e\n```\n\nThe `:format` argument controls output format:\n\n- `:plain`\u003csup\u003edeprecated [v0.18]\u003c/sup\u003e - Just return Avro binary data, with no header or embedded schema\n- `:ocf` - Use [Object Container File][4]\n  format, embedding the full schema with the data\n- `:registry` - Write data with Confluent Schema Registry\n  [Wire Format][3],\n  which prefixes the data with the schema id\n- `:guess` - Use `:registry` if possible, otherwise use `:ocf` (default)\n\n```elixir\n{:ok, pid} = Avrora.start_link()\nmessage = %{\"id\" =\u003e \"tx-1\", \"amount\" =\u003e 15.99}\n\n{:ok, encoded} = Avrora.encode(message, schema_name: \"io.acme.Payment\", format: :registry)\n\u003c\u003c0, 0, 42, 0, 8, 116, 120, 45, 49, 123, 20, 174, 71, 225, 250, 47, 64\u003e\u003e\n```\n\n### decode/2\n\nDecode `Payment` message using the specified schema\n\n```elixir\n{:ok, pid} = Avrora.start_link()\nmessage = \u003c\u003c0, 0, 42, 0, 8, 116, 120, 45, 49, 123, 20, 174, 71, 225, 250, 47, 64\u003e\u003e\n\n{:ok, decoded} = Avrora.decode(message, schema_name: \"io.acme.Payment\")\n%{\"id\" =\u003e \"tx-1\", \"amount\" =\u003e 15.99}\n```\n\n### decode/1\n\nDecode a message, auto-detecting the schema using magic bytes.\nIt first tries resolving the schema using the integer id in the [wire format][3] header.\n\nNext it tries reading using the [Object Container Files][4] embedded schema.\n\n**NOTE:** Messages encoded with OCF wrapped in a List.\n\n```elixir\n{:ok, pid} = Avrora.start_link()\nmessage =\n  \u003c\u003c79, 98, 106, 1, 3, 204, 2, 20, 97, 118, 114, 111, 46, 99, 111, 100, 101, 99,\n    8, 110, 117, 108, 108, 22, 97, 118, 114, 111, 46, 115, 99, 104, 101, 109, 97,\n    144, 2, 123, 34, 110, 97, 109, 101, 115, 112, 97, 99, 101, 34, 58, 34, 105,\n    111, 46, 99, 111, 110, 102, 108, 117, 101, 110, 116, 34, 44, 34, 110, 97, 109,\n    101, 34, 58, 34, 80, 97, 121, 109, 101, 110, 116, 34, 44, 34, 116, 121, 112,\n    101, 34, 58, 34, 114, 101, 99, 111, 114, 100, 34, 44, 34, 102, 105, 101, 108,\n    100, 115, 34, 58, 91, 123, 34, 110, 97, 109, 101, 34, 58, 34, 105, 100, 34, 44,\n    34, 116, 121, 112, 101, 34, 58, 34, 115, 116, 114, 105, 110, 103, 34, 125, 44,\n    123, 34, 110, 97, 109, 101, 34, 58, 34, 97, 109, 111, 117, 110, 116, 34, 44,\n    34, 116, 121, 112, 101, 34, 58, 34, 100, 111, 117, 98, 108, 101, 34, 125, 93,\n    125, 0, 84, 229, 97, 195, 95, 74, 85, 204, 143, 132, 4, 241, 94, 197, 178, 106,\n    2, 26, 8, 116, 120, 45, 49, 123, 20, 174, 71, 225, 250, 47, 64, 84, 229, 97,\n    195, 95, 74, 85, 204, 143, 132, 4, 241, 94, 197, 178, 106\u003e\u003e\n\n{:ok, decoded} = Avrora.decode(message)\n[%{\"id\" =\u003e \"tx-1\", \"amount\" =\u003e 15.99}]\n```\n\n:bulb: Due to [possible collision][10] of the `:plain` format and `:registry` via magic-like\nbyte sequence it's recommended\u003csup\u003e[v0.18]\u003c/sup\u003e to use `Avrora.decode_plain/2` and `Avrora.encode_plain/2` if\nyou are working with `:plain` format (see in all available functions).\n\n\u003cdetails class=\"nodoc\"\u003e\n  \u003csummary\u003e:mag: Click to expand for all available functions\u003c/summary\u003e\n\n### decode_plain/2\u003csup\u003e[0.18]\u003c/sup\u003e\n\nDecode a message encoded in a `:plain` format.\n\n```elixir\n{:ok, pid} = Avrora.start_link()\nmessage = \u003c\u003c8, 116, 120, 45, 49, 123, 20, 174, 71, 225, 250, 47, 64\u003e\u003e\n\n{:ok, decoded} = Avrora.decode(message, schema_name: \"io.acme.Payment\")\n%{\"id\" =\u003e \"tx-1\", \"amount\" =\u003e 15.99}\n```\n\n### encode_plain/2\u003csup\u003e[0.18]\u003c/sup\u003e\n\nEncode a payload in a `:plain` format.\n\n```elixir\n{:ok, pid} = Avrora.start_link()\nmessage = %{\"id\" =\u003e \"tx-1\", \"amount\" =\u003e 15.99}\n\n{:ok, encoded} = Avrora.encode(message, schema_name: \"io.acme.Payment\")\n\u003c\u003c8, 116, 120, 45, 49, 123, 20, 174, 71, 225, 250, 47, 64\u003e\u003e\n```\n\n### extract_schema/1\n\nExtracts a schema from the encoded message, useful when you would like to have\nsome metadata about the schema used to encode the message. All the retrieved schemas\nwill be cached accordingly to the settings.\n\n```elixir\n{:ok, pid} = Avrora.start_link()\nmessage =\n  \u003c\u003c79, 98, 106, 1, 3, 204, 2, 20, 97, 118, 114, 111, 46, 99, 111, 100, 101, 99,\n    8, 110, 117, 108, 108, 22, 97, 118, 114, 111, 46, 115, 99, 104, 101, 109, 97,\n    144, 2, 123, 34, 110, 97, 109, 101, 115, 112, 97, 99, 101, 34, 58, 34, 105,\n    111, 46, 99, 111, 110, 102, 108, 117, 101, 110, 116, 34, 44, 34, 110, 97, 109,\n    101, 34, 58, 34, 80, 97, 121, 109, 101, 110, 116, 34, 44, 34, 116, 121, 112,\n    101, 34, 58, 34, 114, 101, 99, 111, 114, 100, 34, 44, 34, 102, 105, 101, 108,\n    100, 115, 34, 58, 91, 123, 34, 110, 97, 109, 101, 34, 58, 34, 105, 100, 34, 44,\n    34, 116, 121, 112, 101, 34, 58, 34, 115, 116, 114, 105, 110, 103, 34, 125, 44,\n    123, 34, 110, 97, 109, 101, 34, 58, 34, 97, 109, 111, 117, 110, 116, 34, 44,\n    34, 116, 121, 112, 101, 34, 58, 34, 100, 111, 117, 98, 108, 101, 34, 125, 93,\n    125, 0, 84, 229, 97, 195, 95, 74, 85, 204, 143, 132, 4, 241, 94, 197, 178, 106,\n    2, 26, 8, 116, 120, 45, 49, 123, 20, 174, 71, 225, 250, 47, 64, 84, 229, 97,\n    195, 95, 74, 85, 204, 143, 132, 4, 241, 94, 197, 178, 106\u003e\u003e\n\n{:ok, schema} = Avrora.extract_schema(message)\n{:ok,\n %Avrora.Schema{\n   full_name: \"io.acme.Payment\",\n   id: nil,\n   json: \"{\\\"namespace\\\":\\\"io.acme\\\",\\\"name\\\":\\\"Payment\\\",\\\"type\\\":\\\"record\\\",\\\"fields\\\":[{\\\"name\\\":\\\"id\\\",\\\"type\\\":\\\"string\\\"},{\\\"name\\\":\\\"amount\\\",\\\"type\\\":\\\"double\\\"}]}\",\n   lookup_table: #Reference\u003c0.146116641.3853647878.152744\u003e,\n   version: nil\n }}\n```\n\n\u003c/details\u003e\n\n## Schemas registration\n\nThere are two ways you can register AVRO schemas if you have disabled auto-registration.\n\nIf you want to make it a part of your code, but with better control, you can use\n`Avrora.Utils.Registrar` module and if you want to embed it in the deployment use\na mix task `avrora.reg.schema`.\n\n### Avrora.Utils.Registrar\u003csup\u003e[v0.16]\u003c/sup\u003e\n\nThis module is cache-aware and thus it can be used inside intensive loops if needed.\nIt provides two ways to register schema:\n\n- by name, then it will be resolved to a file with [library conventions][9]\n- by schema, then a given schema will be used without any disk reads\n\nBut keep in mind that either way has a memory check to ensure that schema was not\nregistered before and to bypass this check you have to use `force: true` flag\n\n```elixir\n{:ok, schema} = Avrora.Utils.Registrar.register_schema_by_name(\"io.acme.Payment\", force: true)\n```\n\nIn addition, any schema can be registered under different subject via `as: \"NewName\"` option\n\n```elixir\n{:ok, schema} = Avrora.Storage.File.get(\"io.acme.Payment\")\n{:ok, schema_with_id} = Avrora.Utils.Registrar.register_schema(schema, as: \"NewName\")\n```\n\n### mix avrora.reg.schema\u003csup\u003e[v0.12]\u003c/sup\u003e\n\nA separate mix task to register a specific schema or all found schemas in\nschemas folder (see [configuration](#configuration) section).\n\nFor instance, if you configure Avrora schemas folder to be at `./priv/schemas`\nand you want to register a schema `io/acme/Payment.avsc` then you can use\nthis command\n\n```console\n$ mix avrora.reg.schema --name io.acme.Payment\nschema `io.acme.Payment' will be registered\n```\n\nIn addition, any schema can be registered under different subject via `--as` option\u003csup\u003e[v0.16]\u003c/sup\u003e\n\n```console\n$ mix avrora.reg.schema --name io.acme.Payment --as MyCustomName\nschema `io.acme.Payment' will be registered as `MyCustomName'\n```\n\nIf you would like to register all schemas found under `./priv/schemas` then you\ncan simply execute this command\n\n```console\n$ mix avrora.reg.schema --all\nschema `io.acme.Payment' will be registered\nschema `io.acme.Wrong' will be skipped due to an error `argument error'\n```\n\nAdditional application config to load additional can be set via `--appconfig` option\u003csup\u003e[v0.26]\u003c/sup\u003e\n\n```console\n$ mix avrora.reg.schema --name io.acme.Payment --appconfig runtime\nschema `io.acme.Payment' will be registered\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstrech%2Favrora","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstrech%2Favrora","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstrech%2Favrora/lists"}