# Protobuf Module Example

In this example the protobuf Lua rock provides a compiler plugin for the protocol buffers compiler `protoc`. The `Person` message in `person.proto` is compiled into a Lua module `person_rb.lua`.

## Prerequisites

Terminal window

```bash
yum install protobuf # or see: https://github.com/google/protobuf#protobuf-runtime-installation

luarocks install protobuf # installs the protobuf rock https://luarocks.org/modules/djungelorm/protobuf
```

Be aware that in this case you must ensure the prerequisites on all the nodes of the cluster.

## Protocol Buffers Message

In `person.proto`

```javascript
syntax = "proto2";

message Person {

  required int32 id = 1;

  required string name = 2;

  optional string email = 3;

}
```

## Compiled Module

In `person_rb.lua`. This was generated by the Lua plugin for `protoc`.

```lua
-- Generated by protobuf; do not edit

local module = {}

local protobuf = require 'protobuf'

module.PERSON = protobuf.Descriptor()

module.PERSON_ID_FIELD = protobuf.FieldDescriptor()

module.PERSON_NAME_FIELD = protobuf.FieldDescriptor()

module.PERSON_EMAIL_FIELD = protobuf.FieldDescriptor()

module.PERSON_ID_FIELD.name = 'id'

module.PERSON_ID_FIELD.full_name = '.Person.id'

module.PERSON_ID_FIELD.number = 1

module.PERSON_ID_FIELD.index = 0

module.PERSON_ID_FIELD.label = 2

module.PERSON_ID_FIELD.has_default_value = false

module.PERSON_ID_FIELD.default_value = 0

module.PERSON_ID_FIELD.type = 5

module.PERSON_ID_FIELD.cpp_type = 1

module.PERSON_NAME_FIELD.name = 'name'

module.PERSON_NAME_FIELD.full_name = '.Person.name'

module.PERSON_NAME_FIELD.number = 2

module.PERSON_NAME_FIELD.index = 1

module.PERSON_NAME_FIELD.label = 2

module.PERSON_NAME_FIELD.has_default_value = false

module.PERSON_NAME_FIELD.default_value = ''

module.PERSON_NAME_FIELD.type = 9

module.PERSON_NAME_FIELD.cpp_type = 9

module.PERSON_EMAIL_FIELD.name = 'email'

module.PERSON_EMAIL_FIELD.full_name = '.Person.email'

module.PERSON_EMAIL_FIELD.number = 3

module.PERSON_EMAIL_FIELD.index = 2

module.PERSON_EMAIL_FIELD.label = 1

module.PERSON_EMAIL_FIELD.has_default_value = false

module.PERSON_EMAIL_FIELD.default_value = ''

module.PERSON_EMAIL_FIELD.type = 9

module.PERSON_EMAIL_FIELD.cpp_type = 9

module.PERSON.name = 'Person'

module.PERSON.full_name = '.Person'

module.PERSON.nested_types = {}

module.PERSON.enum_types = {}

module.PERSON.fields = {module.PERSON_ID_FIELD, module.PERSON_NAME_FIELD, module.PERSON_EMAIL_FIELD}

module.PERSON.is_extendable = false

module.PERSON.extensions = {}

module.Person = protobuf.Message(module.PERSON)

module.MESSAGE_TYPES = {'Person'}

module.ENUM_TYPES = {}

return module
```

## UDF Module

In the UDF module `pbuf.lua`

```lua
-- Adopted the example from djungelorm/protobuf-lua

function vartix(rec, id, name, email)

  local person_pb = require "person_pb"

  -- Serialize Example

  local msg = person_pb.Person()

  msg.id = id

  msg.name = name

  msg.email = email

  local pb_data = msg:SerializeToString()

  local pb_bytes = bytes(pb_data:len())

  bytes.set_type(pb_bytes, 4)

  bytes.set_string(pb_bytes, 1, pb_data)

  rec["person"] = pb_bytes

  if aerospike:exists(rec) then

    aerospike:update(rec)

  else

    aerospike:create(rec)

  end

end

function velkor(rec)

  local person_pb = require "person_pb"

  -- Parse Example

  local pb_bytes = rec["person"]

  local pb_data = bytes.get_string(pb_bytes, 1, bytes.size(pb_bytes))

  local msg = person_pb.Person()

  msg:ParseFromString(pb_data)

  return msg.id

end

function is_bytes(rec, bin)

  local t = rec[bin]

  return getmetatable(t) == getmetatable(bytes())

end
```

## Registering the Modules

Terminal window

```bash
$ aql

Aerospike Query Client

Version 3.15.3.6

C Client Version 4.3.11

Copyright 2012-2017 Aerospike. All rights reserved.

aql> register module 'pbuf.lua'

OK, 1 module added.

aql> register module 'person_pb.lua'

OK, 1 module added.

aql> show modules

+-----------------+--------------------------------------------+-------+

| filename        | hash                                       | type  |

+-----------------+--------------------------------------------+-------+

| "person_pb.lua" | "e6dee5a956d7be0e8c016df612465c45e39bdd0a" | "LUA" |

| "pbuf.lua"      | "9c714c1e2bbff24cea7531aac881f771ab9a896b" | "LUA" |

+-----------------+--------------------------------------------+-------+

2 rows in set (0.003 secs)
```

## Example

See the [example](https://aerospike.com/docs/database/advanced/udf/modules/record/develop/#example-using-protobuf) for calling the UDF.