Skip to content

Commit

Permalink
Address comments
Browse files Browse the repository at this point in the history
  • Loading branch information
bufdev committed Sep 18, 2020
1 parent 3dc9fd8 commit f226fd2
Show file tree
Hide file tree
Showing 25 changed files with 232 additions and 129 deletions.
16 changes: 8 additions & 8 deletions clientcompat/internal/clientcompat/clientcompat.twirp.go

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

32 changes: 32 additions & 0 deletions docs/interceptors.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
id: "interceptors"
title: "Interceptors"
sidebar_label: "Interceptor"
---

The service constructor can use the option `twirp.WithServerInterceptors(interceptors ...twirp.Interceptor)`
to plug in additional functionality:

```go
server := NewHaberdasherServer(svcImpl, twirp.WithInterceptor(NewLogInterceptor(logger.New(os.Stderr, "", 0))))

// NewLogInterceptor logs various parts of a request using a standard Logger.
func NewLogInterceptor(l *log.Logger) twirp.Interceptor {
return func(next twirp.Method) twirp.Method {
return func(ctx context.Context, req interface{}) (interface{}, error) {
l.Printf("request: %v", request)
resp, err := next(ctx, req)
if err != nil {
l.Printf("error: %v", err)
return nil, err
}
l.Printf("response: %v", resp)
return resp, nil
}
}
}
```

Check out
[the godoc for `Interceptor`](http://godoc.org/github.com/twitchtv/twirp#Interceptors)
for more information.
8 changes: 4 additions & 4 deletions example/service.twirp.go

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

68 changes: 68 additions & 0 deletions interceptors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2018 Twitch Interactive, Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
// use this file except in compliance with the License. A copy of the License is
// located at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// or in the "license" file accompanying this file. This file is distributed on
// an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
// express or implied. See the License for the specific language governing
// permissions and limitations under the License.
package twirp

import (
"context"
)

// Method is a method that matches the generic form of a Twirp-generated RPC method.
//
// This is used for Interceptors.
type Method func(ctx context.Context, request interface{}) (interface{}, error)

// Interceptor is an interceptor that can be installed on a client or server.
//
// Users can use Interceptors to intercept any RPC.
//
// func LogInterceptor(l *log.Logger) twirp.Interceptor {
// return func(next twirp.Method) twirp.Method {
// return func(ctx context.Context, req interface{}) (interface{}, error) {
// l.Printf("request: %v", request)
// resp, err := next(ctx, req)
// if err != nil {
// l.Printf("error: %v", err)
// return nil, err
// }
// l.Printf("response: %v", resp)
// return resp, nil
// }
// }
// }
type Interceptor func(Method) Method

// ChainInterceptors chains the Interceptors.
//
// Returns nil if interceptors is empty.
func ChainInterceptors(interceptors ...Interceptor) Interceptor {
filtered := make([]Interceptor, 0, len(interceptors))
for _, interceptor := range interceptors {
if interceptor != nil {
filtered = append(filtered, interceptor)
}
}
switch n := len(filtered); n {
case 0:
return nil
case 1:
return filtered[0]
default:
first := filtered[0]
return func(next Method) Method {
for i := len(filtered) - 1; i > 0; i-- {
next = filtered[i](next)
}
return first(next)
}
}
}
14 changes: 14 additions & 0 deletions middleware_test.go → interceptors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ func TestChainInterceptors(t *testing.T) {
if chain := ChainInterceptors(); chain != nil {
t.Errorf("ChainInterceptors(0) expected to be nil, but was %v", chain)
}
if chain := ChainInterceptors(nil); chain != nil {
t.Errorf("ChainInterceptors(0) expected to be nil, but was %v", chain)
}
if chain := ChainInterceptors(nil, nil); chain != nil {
t.Errorf("ChainInterceptors(0) expected to be nil, but was %v", chain)
}

interceptor1 := func(next Method) Method {
return func(ctx context.Context, request interface{}) (interface{}, error) {
Expand Down Expand Up @@ -59,6 +65,14 @@ func TestChainInterceptors(t *testing.T) {
interceptors: []Interceptor{interceptor1, interceptor2, interceptor3},
want: "abcx321",
},
{
interceptors: []Interceptor{interceptor1, interceptor2, nil, interceptor3},
want: "abcx321",
},
{
interceptors: []Interceptor{interceptor1, interceptor1, interceptor1},
want: "aaax111",
},
} {
response, err := ChainInterceptors(testCase.interceptors...)(method)(context.Background(), "")
if err != nil {
Expand Down
8 changes: 4 additions & 4 deletions internal/twirptest/gogo_compat/service.twirp.go

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

8 changes: 4 additions & 4 deletions internal/twirptest/google_protobuf_imports/service.twirp.go

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

8 changes: 4 additions & 4 deletions internal/twirptest/importable/importable.twirp.go

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

8 changes: 4 additions & 4 deletions internal/twirptest/importer/importer.twirp.go

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

Loading

0 comments on commit f226fd2

Please sign in to comment.