|
1 | | -# protoc-gen-atlas-query-validate |
| 1 | +# protoc-gen-atlas-query-validate |
| 2 | + |
| 3 | +### Purpose |
| 4 | + |
| 5 | +A [protobuf](https://developers.google.com/protocol-buffers/) compiler plugin |
| 6 | +designed to simplify validation of [Atlas](https://github.com/infobloxopen/atlas-app-toolkit) |
| 7 | +[gRPC](https://grpc.io/) List [query](https://github.com/infobloxopen/atlas-app-toolkit/blob/master/query/collection_operators.proto) parameters |
| 8 | +by generating .pb.atlas.query.validate.go files with validation rules and functions. |
| 9 | +Currently query.Filtering and query.Sorting are supported for validation. |
| 10 | + |
| 11 | +### Prerequisites |
| 12 | + |
| 13 | +#### 1. Protobuf Compiler |
| 14 | + |
| 15 | +The protobuf compiler (protoc) is required. |
| 16 | + |
| 17 | +[Official instructions](https://github.com/google/protobuf#protocol-compiler-installation) |
| 18 | + |
| 19 | +[Abbreviated version](https://github.com/grpc-ecosystem/grpc-gateway#installation) |
| 20 | + |
| 21 | +#### 2. Golang Protobuf Code Generator |
| 22 | + |
| 23 | +Get the golang protobuf code generator: |
| 24 | + |
| 25 | +``` |
| 26 | +go get -u github.com/golang/protobuf/protoc-gen-go |
| 27 | +``` |
| 28 | + |
| 29 | +#### 3. Vendored Dependencies |
| 30 | + |
| 31 | +Retrieve and install the vendored dependencies for this project with [dep](https://github.com/golang/dep): |
| 32 | + |
| 33 | +``` |
| 34 | +dep ensure |
| 35 | +``` |
| 36 | + |
| 37 | +### Installation |
| 38 | + |
| 39 | +To use this tool, install it from code with `make install`, `go install` directly, |
| 40 | +or `go get github.com/infobloxopen/protoc-gen-atlas-query-validate`. |
| 41 | + |
| 42 | +### Usage |
| 43 | + |
| 44 | +Once installed, the `atlas-query-validate_out=.` or `--atlas-query-validate_out=${GOPATH}src` |
| 45 | +option can be specified in a protoc command to generate the .pb.atlas.query.validate.go files. |
| 46 | + |
| 47 | +#### Validation rules |
| 48 | + |
| 49 | +Validation rules are generated for each gRPC method containing query.Filtering and/or query.Sorting in it's request message |
| 50 | +based on the message included in the method's response message(will call it *resource message* for the rest of the document). |
| 51 | + |
| 52 | +By default all fields of *resource message` are allowed for filtering/sorting. |
| 53 | + |
| 54 | +The list of allowed filtering operators and filtering value type/condition type depends on the *filter_type* of the field, |
| 55 | +which is either taken from `(atlas.query.validate).filter_type` proto field option or is computed by the |
| 56 | +plugin based on the field type if the option is not supplied. Currently *filter_type* can be either STRING or NUMBER. |
| 57 | +The following table shows what is allowed for each *filter_type*: |
| 58 | + |
| 59 | +| | STRING | NUMBER | |
| 60 | +|-------------------------------------|--------|--------| |
| 61 | +| **Filtering operators** | EQ, MATCH, GT, GE, LT, LE | EQ, GT, GE, LT, LE | |
| 62 | +| **Filtering value type/condition type** | String, null/StringCondition, NullCondition | Number, null/NumberCondition, NullCondition | |
| 63 | + |
| 64 | +The next table shows how *filter_type* is computed from a proto field type: |
| 65 | + |
| 66 | +| Proto field type | filter_type | |
| 67 | +|-----------------------------|---------------| |
| 68 | +| enum | STRING | |
| 69 | +| string | STRING | |
| 70 | +| double | NUMBER | |
| 71 | +| float | NUMBER | |
| 72 | +| int32 | NUMBER | |
| 73 | +| int64 | NUMBER | |
| 74 | +| sint32 | NUMBER | |
| 75 | +| sint64 | NUMBER | |
| 76 | +| uint32 | NUMBER | |
| 77 | +| uint64 | NUMBER | |
| 78 | +| google.protobuf.StringValue | STRING | |
| 79 | +| google.protobuf.DoubleValue | NUMBER | |
| 80 | +| google.protobuf.FloatValue | NUMBER | |
| 81 | +| google.protobuf.Int32Value | NUMBER | |
| 82 | +| google.protobuf.Int64Value | NUMBER | |
| 83 | +| google.protobuf.UInt32Value | NUMBER | |
| 84 | +| google.protobuf.UInt64Value | NUMBER | |
| 85 | +| google.protobuf.Timestamp | STRING | |
| 86 | +| gorm.types.UUID | STRING | |
| 87 | +| gorm.types.UUIDValue | STRING | |
| 88 | +| atlas.rpc.Identifier | STRING | |
| 89 | +| gorm.types.InetValue | STRING | |
| 90 | + |
| 91 | +#### Validation functions |
| 92 | + |
| 93 | +Validation functions are the entry points for the generated functionality. |
| 94 | +The following validation functions are generated: |
| 95 | + |
| 96 | +```golang |
| 97 | +func {Proto_file_name}ValidateFiltering(methodName string, f *query.Filtering) error |
| 98 | +``` |
| 99 | + |
| 100 | +```golang |
| 101 | +func {Proto_file_name}ValidateSorting(methodName string, s *query.Sorting) error |
| 102 | +``` |
| 103 | +Not nil `error` is returned by the functions if validation is not passed. |
| 104 | + |
| 105 | + |
| 106 | +### Customization |
| 107 | + |
| 108 | +Currently only field-level proto options are supported as customization means. We're planning to add method-level options which will override |
| 109 | +field-level options in order to support different validation rules for List methods having the same *resource message*. |
| 110 | + |
| 111 | +* In order to disable sorting for a field set `(atlas.query.validate).disable_sorting` option to `true`. |
| 112 | +```golang |
| 113 | +bool on_vacation = 3 [(atlas.query.validate).disable_sorting = true]; |
| 114 | +``` |
| 115 | + |
| 116 | +* In order to customize the list of allowed filtering operators pass either a set of `(atlas.query.validate).allow` or |
| 117 | +a set of `(atlas.query.validate).deny` options. |
| 118 | + - In case of using `(atlas.query.validate).allow` only specified filtering operators are allowed: |
| 119 | + ```golang |
| 120 | + string first_name = 1 [(atlas.query.validate) = {allow: MATCH, allow: EQ}]; |
| 121 | + ``` |
| 122 | + - In case of using `(atlas.query.validate).deny` all appropriate(for the field type) filtering operators except specified ones are allowed: |
| 123 | + ```golang |
| 124 | + string first_name = 1 [(atlas.query.validate) = {deny: GT, deny: GE, deny: LT, deny: LE}]; |
| 125 | + ``` |
| 126 | +* In order to change default *filter_type* for a field pass `(atlas.query.validate).filter_type` option. |
| 127 | +```golang |
| 128 | +CustomType custom_type_string = 10 [(atlas.query.validate) = {filter_type: STRING}]; |
| 129 | +``` |
| 130 | +* In order to enable filtering/sorting by nested fields set `(atlas.query.validate).enable_nested_fields` option to true |
| 131 | +on the field of a message type. |
| 132 | + |
| 133 | +```golang |
| 134 | +message User { |
| 135 | + Address home_address = 11 [(atlas.query.validate) = {enable_nested_fields: true}]; |
| 136 | + Address work_address = 12; |
| 137 | +} |
| 138 | +
|
| 139 | +message Address { |
| 140 | + string city = 1 [(atlas.query.validate) = {allow: EQ, disable_sorting: true}]; |
| 141 | + string country = 2; |
| 142 | +} |
| 143 | +``` |
| 144 | + |
| 145 | + |
| 146 | +### Examples |
| 147 | + |
| 148 | +The best way to get started with the plugin is to check out our [example](example/example.proto). |
| 149 | +Example .proto files and generated .pb.atlas.query.validate.go demonstrate most of the use cases of the plugin. |
| 150 | + |
| 151 | +Running `make example` will recompile all these test proto files, if you want |
| 152 | +to test the effects of changing the options and fields. |
| 153 | + |
| 154 | +### Limitations |
| 155 | + |
| 156 | +This project is currently in development, and is expected to undergo "breaking" |
| 157 | +(and fixing) changes |
0 commit comments