# Avsc

### NOTE:
  This is a clone of [mtth/avsc](https://github.com/mtth/avsc) repo.

  The reason we have a separate repo is because [CDAP](github.com/caskdata/cdap) supports avro-based schemas which has subtle changes (relaxed rules)

  * Map can support complex types
  * Names can have `-` (hyphens).

So this repo adds those rules to the parser

Pure JavaScript implementation of the [Avro
specification](https://avro.apache.org/docs/current/spec.html).


## Features

+ Blazingly [fast and compact][benchmarks] serialization! Typically faster than
  JSON with much smaller encodings.
+ All the Avro goodness and more: [type inference][type-inference], [schema
  evolution][schema-evolution], and [remote procedure calls][rpc].
+ Support for [serializing arbitrary JavaScript objects][logical-types].
+ Unopinionated [64-bit integer compatibility][custom-long].


## Installation

```bash
$ npm install cdap-avsc
```

`avsc` is compatible with all versions of [node.js][] since `0.11` and major
browsers via [browserify][] (see the full compatibility table
[here][browser-support]). For convenience, you can also find compiled
distributions with the [releases][] (but please host your own copy).


## Documentation

+ [Home][home]
+ [API](https://github.com/mtth/avsc/wiki/API)
+ [Quickstart](https://github.com/mtth/avsc/wiki/Quickstart)
+ [Advanced usage](https://github.com/mtth/avsc/wiki/Advanced-usage)
+ [Benchmarks][benchmarks]


## Examples

Inside a node.js module, or using browserify:

```javascript
const avro = require('cdap-avsc');
```

+ Encode and decode values from a known schema:

  ```javascript
  const type = avro.parse({
    name: 'Pet',
    type: 'record',
    fields: [
      {name: 'kind', type: {name: 'Kind', type: 'enum', symbols: ['CAT', 'DOG']}},
      {name: 'name', type: 'string'}
    ]
  });
  const buf = type.toBuffer({kind: 'CAT', name: 'Albert'}); // Encoded buffer.
  const val = type.fromBuffer(buf); // {kind: 'CAT', name: 'Albert'}
  ```

+ Infer a value's type and encode similar values:

  ```javascript
  const val = {city: 'Cambridge', zipCodes: ['02138', '02139'], visits: 2};
  const type = avro.infer(val);
  // We can now encode the value:
  const buf = type.toBuffer(val);
  // And also any values with a matching structure:
  const bufs = [
    type.toBuffer({city: 'Seattle', zipCodes: ['98101'], visits: 3}),
    type.toBuffer({city: 'NYC', zipCodes: [], visits: 0})
  ];
  ```

+ Get a [readable stream][readable-stream] of decoded values from an Avro
  container file:

  ```javascript
  avro.createFileDecoder('./values.avro')
    .on('metadata', (type) => { /* `type` is the writer's type. */ })
    .on('data', (val) => { /* Do something with the decoded value. */ });
  ```

+ Implement a TCP server for an [IDL-defined][idl] protocol:

  ```javascript
  avro.assemble('./Ping.avdl', (err, attrs) => {
    // Generate the protocol and attach a handler for `ping` messages:
    const protocol = avro.parse(attrs)
      .on('ping', (req, ee, cb) => {
        cb(null, 'pong');
      });
    // Respond on any incoming connection:
    require('net').createServer()
      .on('connection', (con) => {
        protocol.createListener(con);
      })
      .listen(8000);
  });
  ```


[node.js]: https://nodejs.org/en/
[benchmarks]: https://github.com/mtth/avsc/wiki/Benchmarks
[type-inference]: https://github.com/mtth/avsc/wiki/Advanced-usage#type-inference
[schema-evolution]: https://github.com/mtth/avsc/wiki/Advanced-usage#schema-evolution
[logical-types]: https://github.com/mtth/avsc/wiki/Advanced-usage#logical-types
[custom-long]: https://github.com/mtth/avsc/wiki/Advanced-usage#custom-long-types
[readable-stream]: https://nodejs.org/api/stream.html#stream_class_stream_readable
[browserify]: http://browserify.org/
[browser-support]: https://github.com/mtth/avsc/wiki#browser-support
[home]: https://github.com/mtth/avsc/wiki
[rpc]: https://github.com/mtth/avsc/wiki/Advanced-usage#remote-procedure-calls
[releases]: https://github.com/mtth/avsc/releases
[idl]: https://avro.apache.org/docs/current/idl.html
