Skip to content

Commit

Permalink
add fieldmask interceptor
Browse files Browse the repository at this point in the history
  • Loading branch information
linhbkhn95 committed Sep 29, 2024
1 parent 88ca73f commit b1c904f
Show file tree
Hide file tree
Showing 7 changed files with 1,229 additions and 108 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.21
require (
buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.31.0-20230802163732-1c33ebd9ecfa.1
github.com/bufbuild/protovalidate-go v0.2.1
github.com/mennanov/fmutils v0.3.0
github.com/stretchr/testify v1.8.4
golang.org/x/net v0.21.0
golang.org/x/oauth2 v0.16.0
Expand Down
1,005 changes: 1,005 additions & 0 deletions go.sum

Large diffs are not rendered by default.

40 changes: 40 additions & 0 deletions interceptors/fieldmask/interceptor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package fieldmask

import (
"context"

"github.com/mennanov/fmutils"
"google.golang.org/grpc"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/fieldmaskpb"
)

var DefaultFilterFunc FilterFunc = func(msg proto.Message, paths []string) {
fmutils.Filter(msg, paths)
}

type FilterFunc func(msg proto.Message, paths []string)

// UnaryServerInterceptor returns a new unary server interceptor that will decide whether to which fields should return to clients.
func UnaryServerInterceptor(filterFunc FilterFunc) grpc.UnaryServerInterceptor {
return func(ctx context.Context, req any, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp any, err error) {
resp, err = handler(ctx, req)
if err != nil {
return
}
reqWithFieldMask, ok := req.(interface {
GetFieldMask() *fieldmaskpb.FieldMask
})
if !ok {
return
}
if len(reqWithFieldMask.GetFieldMask().GetPaths()) > 0 {
protoResp, ok := resp.(proto.Message)
if !ok {
return
}
filterFunc(protoResp, reqWithFieldMask.GetFieldMask().GetPaths())
}
return
}
}
57 changes: 57 additions & 0 deletions interceptors/fieldmask/interceptor_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright (c) The go-grpc-middleware Authors.
// Licensed under the Apache License 2.0.

// Copyright 2017 David Ackroyd. All Rights Reserved.
// See LICENSE for licensing terms.

package fieldmask

import (
"testing"

"github.com/grpc-ecosystem/go-grpc-middleware/v2/testing/testpb"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
"google.golang.org/grpc"
"google.golang.org/protobuf/types/known/fieldmaskpb"
)

func TestFieldMaskSuite(t *testing.T) {
s := &FieldMaskSuite{
InterceptorTestSuite: &testpb.InterceptorTestSuite{
TestService: &testpb.TestPingService{},
ServerOpts: []grpc.ServerOption{
grpc.UnaryInterceptor(
UnaryServerInterceptor(DefaultFilterFunc),
),
},
},
}
suite.Run(t, s)
}

type FieldMaskSuite struct {
*testpb.InterceptorTestSuite
}

func (s *FieldMaskSuite) TestUnary_ReturnAllResponse() {
resp, err := s.Client.Ping(s.SimpleCtx(), &testpb.PingRequest{Value: "1"})
assert.Equal(s.T(), nil, err)
expected := &testpb.PingResponse{
Value: "1",
}
assert.Equal(s.T(), expected.Counter, resp.Counter)
assert.Equal(s.T(), expected.Value, resp.Value)
}

func (s *FieldMaskSuite) TestUnary_NoReturnValueResponse() {
resp, err := s.Client.Ping(s.SimpleCtx(), &testpb.PingRequest{Value: "1", FieldMask: &fieldmaskpb.FieldMask{
Paths: []string{"counter"},
}})
assert.Equal(s.T(), nil, err)
expected := &testpb.PingResponse{
Value: "",
}
assert.Equal(s.T(), expected.Counter, resp.Counter)
assert.Equal(s.T(), expected.Value, resp.Value)
}
228 changes: 122 additions & 106 deletions testing/testpb/test.pb.go

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion testing/testpb/test_grpc.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion testing/testpb/v1/test.proto
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
syntax = "proto3";

import "google/protobuf/field_mask.proto";

package testing.testpb.v1;

option go_package = ".;testpb";
option go_package = "./;testpb";

message PingEmptyRequest {
}
Expand All @@ -14,6 +16,7 @@ message PingRequest {
string value = 1;
int32 sleep_time_ms = 2;
uint32 error_code_returned = 3;
google.protobuf.FieldMask field_mask = 4;
}

message PingResponse {
Expand Down

0 comments on commit b1c904f

Please sign in to comment.