A protobuf (https://developers.google.com/protocol-buffers/) compiler plugin designed to simplify the API calls needed to perform simple object persistence tasks. This is currently accomplished by creating a secondary .pb.orm.go file which contains sister objects to those generated in the standard .pb.go file satisfying these criteria:
- Go field decorators/tags can be defined by option in the .proto file for GORM/SQL
- There are options for dropping fields from the pb object, or adding additional fields (not generally recommended, as it reduces clarity of .proto file)
- Converters between pb version and ORM version of the objects are included
- Hook interfaces allow for custom application logic
The protobuf compiler (protoc) is required. The official instructions are here, and an abbreviated version can be found here.
Then you will also need the golang code generator
go get -u github.com/golang/protobuf/protoc-gen-go
To use this tool, install it from code with make install, go install directly,
or go get github.com/infobloxopen/protoc-gen-gorm.
Once installed, the --gorm_out=. or --gorm_out=${GOPATH}src
option can be specified in a protoc command to generate the .pb.gorm.go files.
Any message types with the option (gorm.opts).ormable = true will have the
following autogenerated:
- A struct with ORM compatible types and the "ORM" suffix
- Tags copied from the field options
[(gorm.field).tags = "..."] - A {PbType}.ToORM and {TypeORM}.ToPB function
- Barebones C/U/R/D/L handlers that accept the protobuf versions (as from an API call), a context (used with the multiaccount option and for collection operators https://github.com/infobloxopen/atlas-app-toolkit#collection-operators), and a gorm.DB then perform the basic operation on the DB with the object
- Interface hooks for before and after each conversion that can be implemented to add custom handling.
Any services with the option (gorm.server).autogen = true will have basic grpc server generated:
- For service methods with names starting with
Create|Read|Update|Deletegenerated implementation will call basic CRUD handlers. - For other methods
return &MethodResponse{}, nilstub is generated.
For CRUD methods to be generated correctly you need to follow specific conventions:
- Request messages for Create and Update methods should have an Ormable Type
in a field named
payload, for Read and Delete methods anidfield is required. Nothing is required in the List request. - Response messages for Create, Read, and Update require an Ormable Type in a
field named
resultand for List a repeated Ormable Type namedresults. - Delete methods require the
(gorm.method).object_typeoption to indicate which Ormable Type it should delete, and has no response type requirements.
If conventions are not met stubs are generated for CRUD methods. As seen in the feature_demo/demo_service example.
To leverage DB specific features, specify the DB engine during generation using
the --gorm_out="engine={postgres,...}:{path}". Currently only Postgres has
special type support, any other choice will behave as default.
Example .proto files and generated .pb.gorm.go files are included in the 'example' directory. The contacts/contacts.proto mirrors the example project in https://github.com/infobloxopen/atlas-contacts-app, the feature_demo/demo_types file demonstrates the type handling and multi_account functions, and the feature_demo/demo_service shows the service autogeneration.
Running make example will recompile all these test proto files, if you want
to test the effects of changing the options and fields.
Within the proto files, the following types are supported:
- standard primitive types
uint32,uint64,int32,int64,float,double,bool,stringmap to the same type at ORM level - google wrapper types
google.protobuf.StringValue,.BoolValue,.UInt32Value,.FloatValue, etc. map to pointers of the internal type at the ORM level, e.g.*string,*bool,*uint32,*float - [google timestamp type]((https://github.com/golang/protobuf/blob/master/ptypes/timestamp/timestamp.proto)
google.protobuf.Timestampmaps totime.Timetype at the ORM level - custom wrapper type
gorm.types.UUIDValue, which wraps a string and converts to auuid.UUIDtype at the ORM level, from https://github.com/satori/go.uuid - custom wrapper type
gorm.types.JSONValue, which wraps a string in protobuf containing arbitrary JSON and converts topostgres.JsonbGORM type (https://github.com/jinzhu/gorm/blob/master/dialects/postgres/postgres.go#L59) if Postgres is the selected DB engine, otherwise it is currently dropped.
Currently only proto3 is supported.
This project is currently in development, and is expected to undergo "breaking" (and fixing) changes