Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tutorial on how to convert a protobuf message and filter certain fields to a resulting map. #42

Merged
merged 13 commits into from
Feb 15, 2024
2 changes: 2 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,7 @@ jobs:
uses: actions/setup-go@v5
with:
go-version: ${{ matrix.go-version }}
cache: true

- name: Run tests
run: go test -v ./...
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import fieldmask_utils "github.com/mennanov/fieldmask-utils"

// A function that maps field mask field names to the names used in Go structs.
// It has to be implemented according to your needs.
// Scroll down for a reference on how to apply field masks to your gRPC services.
func naming(s string) string {
if s == "foo" {
return "Foo"
Expand Down Expand Up @@ -80,6 +81,47 @@ func main() {
}
```

#### Naming function

For developers that are looking for a mechanism to apply a mask field in their update endpoints using gRPC services,
there are multiple options for the naming function described above:

- Using the `CamelCase` function provided in
the [original protobuf repository](https://github.com/golang/protobuf/blob/master/protoc-gen-go/generator/generator.go#L2648).
This repository has been deprecated and it will potentially trigger lint errors.
- You can copy-paste the `CamelCase` function to your own project or,
- You can use an [Open Source alternative](https://github.com/gojaguar/jaguar) that provides the same functionality,
already took care of [copying the code](https://github.com/gojaguar/jaguar/blob/main/strings/pascal_case.go), and also added tests.

```go
func main() {
mask := &fieldmaskpb.FieldMask{Paths: []string{"username"}}
mask.Normalize()
req := &UpdateUserRequest{
User: &User{
Id: 1234,
Username: "Test",
},
}
if !mask.IsValid(req) {
return
}
protoMask, err := fieldmask_utils.MaskFromProtoFieldMask(mask, strings.PascalCase)
if err != nil {
return
}
m := make(map[string]any)
err = fieldmask_utils.StructToMap(protoMask, req, m)
if err != nil {
return
}
fmt.Println("Resulting map:", m)
}
```

This will result in a map that contains the fields that need to be updated with their respective values.


### Limitations

1. Larger scope field masks have no effect and are not considered invalid:
Expand Down