Skip to content

Commit f3683e5

Browse files
authored
Add more comments to examples (#100)
1 parent a932187 commit f3683e5

File tree

3 files changed

+74
-46
lines changed

3 files changed

+74
-46
lines changed

README.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
# ⚔️ Vanguard
22

3-
[![License](https://img.shields.io/github/license/connectrpc/vanguard-go?color=blue)][badges_license]
4-
[![Slack](https://img.shields.io/badge/slack-buf-%23e01563)][badges_slack]
53
[![Build](https://github.com/connectrpc/vanguard-go/actions/workflows/ci.yaml/badge.svg?branch=main)](https://github.com/connectrpc/vanguard-go/actions/workflows/ci.yaml)
64
[![Report Card](https://goreportcard.com/badge/connectrpc.com/vanguard)](https://goreportcard.com/report/github.com/connectrpc/vanguard-go)
75
[![GoDoc](https://pkg.go.dev/badge/connectrpc.com/vanguard.svg)](https://pkg.go.dev/github.com/connectrpc/vanguard-go)
6+
[![Slack](https://img.shields.io/badge/slack-buf-%23e01563)][badges_slack]
87

98
Vanguard is a powerful library for Go `net/http` servers that enables seamless
109
transcoding between REST and RPC protocols. Whether you need to bridge the gap

transcoder.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ import (
3838
// service handlers support. It can do simple routing based on RPC method name, for simple
3939
// protocols like Connect, gRPC, and gRPC-Web; but it can also route based on REST-ful URI
4040
// paths configured with HTTP transcoding annotations.
41+
//
42+
// See the package-level examples for sample usage.
4143
type Transcoder struct {
4244
bufferPool bufferPool
4345
codecs codecMap

vanguard_examples_test.go

Lines changed: 71 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -38,26 +38,35 @@ import (
3838
"google.golang.org/protobuf/types/known/timestamppb"
3939
)
4040

41-
func ExampleNewTranscoder_restToConnect() {
42-
log := log.New(os.Stdout, "" /* prefix */, 0 /* flags */)
43-
44-
// RPC service implementing testv1connect.LibraryService annotations.
41+
func Example_restClientToRpcServer() {
42+
// This example shows Vanguard adding REST support to an RPC server built
43+
// with Connect. (To add REST, gRPC-Web, and Connect support to servers built
44+
// with grpc-go, use the connectrpc.com/vanguard/vanguardgrpc sub-package.)
45+
logger := log.New(os.Stdout, "" /* prefix */, 0 /* flags */)
46+
47+
// libraryRPC is an implementation of the testv1connect.LibraryService RPC
48+
// server. It's a pure RPC server, without any hand-written translation to or
49+
// from RESTful semantics.
4550
svc := &libraryRPC{}
51+
rpcRoute, rpcHandler := testv1connect.NewLibraryServiceHandler(svc)
4652

47-
handler, err := vanguard.NewTranscoder([]*vanguard.Service{
48-
vanguard.NewService(testv1connect.NewLibraryServiceHandler(svc)),
49-
})
53+
// Using Vanguard, the server can also accept RESTful requests. The Vanguard
54+
// Transcoder handles both REST and RPC traffic, so there's no need to mount
55+
// the RPC-only handler.
56+
services := []*vanguard.Service{vanguard.NewService(rpcRoute, rpcHandler)}
57+
transcoder, err := vanguard.NewTranscoder(services)
5058
if err != nil {
51-
log.Println("error:", err)
59+
logger.Println(err)
5260
return
5361
}
5462

55-
// Create the server.
56-
// (This is a httptest.Server, but it could be any http.Server)
57-
server := httptest.NewServer(handler)
63+
// We can use any server that works with http.Handlers. Since this is a
64+
// testable example, we're using httptest.
65+
server := httptest.NewServer(transcoder)
5866
defer server.Close()
59-
client := server.Client()
6067

68+
// With the server running, we can make a RESTful call.
69+
client := server.Client()
6170
book := &testv1.Book{
6271
Title: "2001: A Space Odyssey",
6372
Author: "Arthur C. Clarke",
@@ -66,61 +75,79 @@ func ExampleNewTranscoder_restToConnect() {
6675
"genre": "science fiction",
6776
},
6877
}
69-
body, _ := protojson.Marshal(book)
78+
body, err := protojson.Marshal(book)
79+
if err != nil {
80+
logger.Println(err)
81+
return
82+
}
7083

71-
// Create the POST request.
72-
req, _ := http.NewRequestWithContext(
84+
req, err := http.NewRequestWithContext(
7385
context.Background(), http.MethodPost,
7486
server.URL+"/v1/shelves/top/books",
7587
bytes.NewReader(body),
7688
)
89+
if err != nil {
90+
logger.Println(err)
91+
return
92+
}
7793
req.Header.Set("Content-Type", "application/json")
7894
req.URL.RawQuery = "book_id=2&request_id=123"
7995

8096
rsp, err := client.Do(req)
8197
if err != nil {
82-
log.Println("error:", err)
98+
logger.Println(err)
8399
return
84100
}
85101
defer rsp.Body.Close()
86-
log.Println(rsp.Status)
87-
log.Println(rsp.Header.Get("Content-Type"))
102+
logger.Println(rsp.Status)
103+
logger.Println(rsp.Header.Get("Content-Type"))
88104

89-
// Decode the response.
90-
body, _ = io.ReadAll(rsp.Body)
91-
92-
_ = protojson.Unmarshal(body, book)
93-
log.Println(book.Author)
105+
body, err = io.ReadAll(rsp.Body)
106+
if err != nil {
107+
logger.Println(err)
108+
return
109+
}
110+
if err := protojson.Unmarshal(body, book); err != nil {
111+
logger.Println(err)
112+
return
113+
}
114+
logger.Println(book.Author)
94115
// Output: 200 OK
95116
// application/json
96117
// Arthur C. Clarke
97118
}
98119

99-
func ExampleNewTranscoder_connectToREST() {
100-
log := log.New(os.Stdout, "" /* prefix */, 0 /* flags */)
101-
102-
// REST service implementing testv1connect.LibraryService annotations.
103-
svc := &libraryREST{}
104-
105-
handler, err := vanguard.NewTranscoder(
106-
[]*vanguard.Service{vanguard.NewService(
107-
testv1connect.LibraryServiceName,
108-
svc,
109-
// This tells vanguard that it must transform requests to REST.
110-
vanguard.WithTargetProtocols(vanguard.ProtocolREST),
111-
)},
112-
)
120+
func Example_rpcClientToRestServer() {
121+
// This example shows Vanguard adding RPC support to an REST server. This
122+
// lets organizations use RPC clients in new codebases without rewriting
123+
// existing REST services.
124+
logger := log.New(os.Stdout, "" /* prefix */, 0 /* flags */)
125+
126+
// libraryREST is an http.Handler that implements a RESTful server. The
127+
// implementation doesn't use Protobuf or RPC directly.
128+
restHandler := &libraryREST{}
129+
130+
// Using Vanguard, the server can also accept RPC traffic. The Vanguard
131+
// Transcoder handles both REST and RPC traffic, so there's no need to mount
132+
// the REST-only handler.
133+
services := []*vanguard.Service{vanguard.NewService(
134+
testv1connect.LibraryServiceName,
135+
restHandler,
136+
// This tells vanguard that the service implementation only supports REST.
137+
vanguard.WithTargetProtocols(vanguard.ProtocolREST),
138+
)}
139+
transcoder, err := vanguard.NewTranscoder(services)
113140
if err != nil {
114-
log.Println("error:", err)
141+
logger.Println(err)
115142
return
116143
}
117144

118-
// Create the server.
119-
// (This is a httptest.Server, but it could be any http.Server)
120-
server := httptest.NewServer(handler)
145+
// We can serve RPC and REST traffic using any server that works with
146+
// http.Handlers. Since this is a testable example, we're using httptest.
147+
server := httptest.NewServer(transcoder)
121148
defer server.Close()
122149

123-
// Create a connect client and call the service.
150+
// With the server running, we can make an RPC call using a generated client.
124151
client := testv1connect.NewLibraryServiceClient(server.Client(), server.URL)
125152
rsp, err := client.GetBook(
126153
context.Background(),
@@ -129,10 +156,10 @@ func ExampleNewTranscoder_connectToREST() {
129156
}),
130157
)
131158
if err != nil {
132-
log.Println("error:", err)
159+
logger.Println(err)
133160
return
134161
}
135-
log.Println(rsp.Msg.Description)
162+
logger.Println(rsp.Msg.Description)
136163
// Output: Have you seen Blade Runner?
137164
}
138165

0 commit comments

Comments
 (0)