├── .gitignore ├── LICENSE ├── README.md ├── go.mod ├── go.sum ├── grpcserver ├── go.mod ├── go.sum └── main.go ├── http_test.go ├── pb ├── go.mod ├── go.sum ├── random.pb.go └── random.proto ├── random.go ├── rest_grpc_test.go ├── restserver ├── go.mod ├── go.sum └── main.go └── server ├── go.mod ├── go.sum ├── main.go ├── server.crt └── server.key /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, build with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Bimesh De Silva 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gRPC vs. REST: Performance Simplified 2 | Check out my article here: https://medium.com/@bimeshde/grpc-vs-rest-performance-simplified-fd35d01bbd4 3 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/Bimde/grpc-vs-rest 2 | 3 | go 1.12 4 | 5 | require ( 6 | github.com/Bimde/grpc-vs-rest/pb v0.0.0-20190510020245-d0b8e3a579ad 7 | github.com/golang/protobuf v1.3.1 8 | github.com/rogpeppe/godef v1.1.1 // indirect 9 | golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284 // indirect 10 | golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 11 | golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862 // indirect 12 | golang.org/x/text v0.3.2 // indirect 13 | golang.org/x/tools v0.0.0-20190509153222-73554e0f7805 // indirect 14 | google.golang.org/grpc v1.20.1 15 | ) 16 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | 9fans.net/go v0.0.0-20181112161441-237454027057 h1:OcHlKWkAMJEF1ndWLGxp5dnJQkYM/YImUOvsBoz6h5E= 2 | 9fans.net/go v0.0.0-20181112161441-237454027057/go.mod h1:diCsxrliIURU9xsYtjCp5AbpQKqdhKmf0ujWDUSkfoY= 3 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 4 | github.com/Bimde/grpc-vs-rest/pb v0.0.0-20190510020245-d0b8e3a579ad h1:q7kzkDjKWY6tjnu504+QMb/2ClnM+keD4nyfd8JFE6I= 5 | github.com/Bimde/grpc-vs-rest/pb v0.0.0-20190510020245-d0b8e3a579ad/go.mod h1:imKC554J18WtRMRaEfmlRZWPhBByETTbgZR7cYAsklw= 6 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 7 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 8 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= 9 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 10 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 11 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 12 | github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= 13 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 14 | github.com/rogpeppe/godef v1.1.1 h1:NujOtt9q9vIClRTB3sCZpavac+NMRaIayzrcz1h4fSE= 15 | github.com/rogpeppe/godef v1.1.1/go.mod h1:oEo1eMy1VUEHUzUIX4F7IqvMJRiz9UId44mvnR8oPlQ= 16 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 17 | golang.org/x/crypto v0.0.0-20190506204251-e1dfcc566284/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 18 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 19 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 20 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 21 | golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 h1:6M3SDHlHHDCx2PcQw3S4KsR170vGqDhJDOmpVd4Hjak= 22 | golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 23 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 24 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 25 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 26 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 27 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 28 | golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862 h1:rM0ROo5vb9AdYJi1110yjWGMej9ITfKddS89P3Fkhug= 29 | golang.org/x/sys v0.0.0-20190509141414-a5b02f93d862/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 30 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 31 | golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= 32 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 33 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 34 | golang.org/x/tools v0.0.0-20181130195746-895048a75ecf/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 35 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 36 | golang.org/x/tools v0.0.0-20190509153222-73554e0f7805 h1:1ufBXAsTpUhSmmPXEEs5PrGQSfnBhsjAd2SmVhp9xrY= 37 | golang.org/x/tools v0.0.0-20190509153222-73554e0f7805/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 38 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 39 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= 40 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 41 | google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU= 42 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= 43 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 44 | -------------------------------------------------------------------------------- /grpcserver/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/Bimde/grpc-vs-rest/grpcserver 2 | 3 | go 1.12 4 | 5 | require ( 6 | github.com/Bimde/grpc-vs-rest/pb v0.0.0-20190511165804-4eb8cce79d5b 7 | golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 8 | google.golang.org/grpc v1.20.1 9 | ) 10 | -------------------------------------------------------------------------------- /grpcserver/go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | github.com/Bimde/grpc-vs-rest/pb v0.0.0-20190511165804-4eb8cce79d5b h1:J7y7JOEqFEM39mN2fsCkgWHqsfxv5z2bO/8TkyNpFHI= 3 | github.com/Bimde/grpc-vs-rest/pb v0.0.0-20190511165804-4eb8cce79d5b/go.mod h1:imKC554J18WtRMRaEfmlRZWPhBByETTbgZR7cYAsklw= 4 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 5 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 6 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 7 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 8 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 9 | github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= 10 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 11 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 12 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 13 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 14 | golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 h1:6M3SDHlHHDCx2PcQw3S4KsR170vGqDhJDOmpVd4Hjak= 15 | golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 16 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 17 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 18 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= 19 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 20 | golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= 21 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 22 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 23 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 24 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= 25 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 26 | google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU= 27 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= 28 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 29 | -------------------------------------------------------------------------------- /grpcserver/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "net" 6 | 7 | "golang.org/x/net/context" 8 | "google.golang.org/grpc" 9 | 10 | "github.com/Bimde/grpc-vs-rest/pb" 11 | ) 12 | 13 | type server struct{} 14 | 15 | func main() { 16 | lis, err := net.Listen("tcp", ":9090") 17 | if err != nil { 18 | log.Fatalf("Failed to listen: %v", err) 19 | } 20 | s := grpc.NewServer() 21 | pb.RegisterRandomServiceServer(s, &server{}) 22 | log.Println("Starting gRPC server") 23 | if err := s.Serve(lis); err != nil { 24 | log.Fatalf("Failed to serve: %v", err) 25 | } 26 | } 27 | 28 | func (s *server) DoSomething(_ context.Context, random *pb.Random) (*pb.Random, error) { 29 | random.RandomString = "[Updated] " + random.RandomString 30 | return random, nil 31 | } 32 | -------------------------------------------------------------------------------- /http_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "crypto/tls" 5 | "crypto/x509" 6 | "testing" 7 | 8 | //"testing" 9 | "encoding/json" 10 | "io/ioutil" 11 | "log" 12 | "net/http" 13 | "sync" 14 | 15 | //"golang.org/x/net/http2" 16 | "github.com/Bimde/grpc-vs-rest/pb" 17 | "golang.org/x/net/http2" 18 | ) 19 | 20 | var client http.Client 21 | 22 | func init() { 23 | client = http.Client{} 24 | } 25 | 26 | // This code was taken from https://posener.github.io/http2/ 27 | func createTLSConfigWithCustomCert() *tls.Config { 28 | // Create a pool with the server certificate since it is not signed 29 | // by a known CA 30 | caCert, err := ioutil.ReadFile("server/server.crt") 31 | if err != nil { 32 | log.Fatalf("Reading server certificate: %s", err) 33 | } 34 | caCertPool := x509.NewCertPool() 35 | caCertPool.AppendCertsFromPEM(caCert) 36 | 37 | // Create TLS configuration with the certificate of the server 38 | return &tls.Config{ 39 | RootCAs: caCertPool, 40 | } 41 | } 42 | 43 | // func BenchmarkHTTP2Get(b *testing.B) { 44 | // client.Transport = &http2.Transport{ 45 | // TLSClientConfig: createTLSConfigWithCustomCert(), 46 | // } 47 | 48 | // var wg sync.WaitGroup 49 | // wg.Add(b.N) 50 | // for i := 0; i < b.N; i++ { 51 | // go func() { 52 | // get("https://bimde:8080", &pb.Random{}) 53 | // wg.Done() 54 | // }() 55 | // } 56 | // wg.Wait() 57 | // } 58 | 59 | func get(path string, output interface{}) error { 60 | req, err := http.NewRequest("GET", path, nil) 61 | if err != nil { 62 | log.Println("error creating request ", err) 63 | return err 64 | } 65 | 66 | res, err := client.Do(req) 67 | if err != nil { 68 | log.Println("error executing request ", err) 69 | return err 70 | } 71 | 72 | bytes, err := ioutil.ReadAll(res.Body) 73 | if err != nil { 74 | log.Println("error reading response body ", err) 75 | return err 76 | } 77 | 78 | err = json.Unmarshal(bytes, output) 79 | if err != nil { 80 | log.Println("error unmarshalling response ", err) 81 | return err 82 | } 83 | 84 | return nil 85 | } 86 | 87 | type Request struct { 88 | Path string 89 | Random *pb.Random 90 | } 91 | 92 | const stopRequestPath = "STOP" 93 | const noWorkers = 4096 94 | 95 | func BenchmarkHTTP2GetWithWokers(b *testing.B) { 96 | client.Transport = &http2.Transport{ 97 | TLSClientConfig: createTLSConfigWithCustomCert(), 98 | } 99 | requestQueue := make(chan Request) 100 | defer startWorkers(&requestQueue, noWorkers, startWorker)() 101 | b.ResetTimer() // don't count worker initialization time 102 | for i := 0; i < b.N; i++ { 103 | requestQueue <- Request{Path: "https://bimde:8080", Random: &pb.Random{}} 104 | } 105 | } 106 | 107 | func BenchmarkHTTP11Get(b *testing.B) { 108 | client.Transport = &http.Transport{ 109 | TLSClientConfig: createTLSConfigWithCustomCert(), 110 | } 111 | requestQueue := make(chan Request) 112 | defer startWorkers(&requestQueue, noWorkers, startWorker)() 113 | b.ResetTimer() // don't count worker initialization time 114 | for i := 0; i < b.N; i++ { 115 | requestQueue <- Request{Path: "https://bimde:8080", Random: &pb.Random{}} 116 | } 117 | } 118 | 119 | func startWorkers(requestQueue *chan Request, noWorkers int, startWorker func(*chan Request, *sync.WaitGroup)) func() { 120 | var wg sync.WaitGroup 121 | for i := 0; i < noWorkers; i++ { 122 | startWorker(requestQueue, &wg) 123 | } 124 | return func() { 125 | wg.Add(noWorkers) 126 | stopRequest := Request{Path: stopRequestPath} 127 | for i := 0; i < noWorkers; i++ { 128 | *requestQueue <- stopRequest 129 | } 130 | wg.Wait() 131 | } 132 | } 133 | 134 | func startWorker(requestQueue *chan Request, wg *sync.WaitGroup) { 135 | go func() { 136 | for { 137 | request := <-*requestQueue 138 | if request.Path == stopRequestPath { 139 | wg.Done() 140 | return 141 | } 142 | get(request.Path, request.Random) 143 | } 144 | }() 145 | } 146 | -------------------------------------------------------------------------------- /pb/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/Bimde/grpc-vs-rest/pb 2 | 3 | go 1.12 4 | 5 | require ( 6 | github.com/golang/protobuf v1.3.1 7 | golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 8 | google.golang.org/grpc v1.20.1 9 | ) 10 | -------------------------------------------------------------------------------- /pb/go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 3 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 4 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 5 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 6 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 7 | github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= 8 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 9 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 10 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 11 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 12 | golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 h1:6M3SDHlHHDCx2PcQw3S4KsR170vGqDhJDOmpVd4Hjak= 13 | golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 14 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 15 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 16 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= 17 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 18 | golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= 19 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 20 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 21 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 22 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= 23 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 24 | google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU= 25 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= 26 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 27 | -------------------------------------------------------------------------------- /pb/random.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // source: random.proto 3 | 4 | package pb 5 | 6 | import proto "github.com/golang/protobuf/proto" 7 | import fmt "fmt" 8 | import math "math" 9 | 10 | import ( 11 | context "golang.org/x/net/context" 12 | grpc "google.golang.org/grpc" 13 | ) 14 | 15 | // Reference imports to suppress errors if they are not otherwise used. 16 | var _ = proto.Marshal 17 | var _ = fmt.Errorf 18 | var _ = math.Inf 19 | 20 | // This is a compile-time assertion to ensure that this generated file 21 | // is compatible with the proto package it is being compiled against. 22 | // A compilation error at this line likely means your copy of the 23 | // proto package needs to be updated. 24 | const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package 25 | 26 | type Random struct { 27 | RandomString string `protobuf:"bytes,1,opt,name=randomString,proto3" json:"randomString,omitempty"` 28 | RandomInt int32 `protobuf:"varint,2,opt,name=randomInt,proto3" json:"randomInt,omitempty"` 29 | XXX_NoUnkeyedLiteral struct{} `json:"-"` 30 | XXX_unrecognized []byte `json:"-"` 31 | XXX_sizecache int32 `json:"-"` 32 | } 33 | 34 | func (m *Random) Reset() { *m = Random{} } 35 | func (m *Random) String() string { return proto.CompactTextString(m) } 36 | func (*Random) ProtoMessage() {} 37 | func (*Random) Descriptor() ([]byte, []int) { 38 | return fileDescriptor_random_2b8f171ebf7b1d7e, []int{0} 39 | } 40 | func (m *Random) XXX_Unmarshal(b []byte) error { 41 | return xxx_messageInfo_Random.Unmarshal(m, b) 42 | } 43 | func (m *Random) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { 44 | return xxx_messageInfo_Random.Marshal(b, m, deterministic) 45 | } 46 | func (dst *Random) XXX_Merge(src proto.Message) { 47 | xxx_messageInfo_Random.Merge(dst, src) 48 | } 49 | func (m *Random) XXX_Size() int { 50 | return xxx_messageInfo_Random.Size(m) 51 | } 52 | func (m *Random) XXX_DiscardUnknown() { 53 | xxx_messageInfo_Random.DiscardUnknown(m) 54 | } 55 | 56 | var xxx_messageInfo_Random proto.InternalMessageInfo 57 | 58 | func (m *Random) GetRandomString() string { 59 | if m != nil { 60 | return m.RandomString 61 | } 62 | return "" 63 | } 64 | 65 | func (m *Random) GetRandomInt() int32 { 66 | if m != nil { 67 | return m.RandomInt 68 | } 69 | return 0 70 | } 71 | 72 | func init() { 73 | proto.RegisterType((*Random)(nil), "pb.Random") 74 | } 75 | 76 | // Reference imports to suppress errors if they are not otherwise used. 77 | var _ context.Context 78 | var _ grpc.ClientConn 79 | 80 | // This is a compile-time assertion to ensure that this generated file 81 | // is compatible with the grpc package it is being compiled against. 82 | const _ = grpc.SupportPackageIsVersion4 83 | 84 | // RandomServiceClient is the client API for RandomService service. 85 | // 86 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. 87 | type RandomServiceClient interface { 88 | DoSomething(ctx context.Context, in *Random, opts ...grpc.CallOption) (*Random, error) 89 | } 90 | 91 | type randomServiceClient struct { 92 | cc *grpc.ClientConn 93 | } 94 | 95 | func NewRandomServiceClient(cc *grpc.ClientConn) RandomServiceClient { 96 | return &randomServiceClient{cc} 97 | } 98 | 99 | func (c *randomServiceClient) DoSomething(ctx context.Context, in *Random, opts ...grpc.CallOption) (*Random, error) { 100 | out := new(Random) 101 | err := c.cc.Invoke(ctx, "/pb.RandomService/DoSomething", in, out, opts...) 102 | if err != nil { 103 | return nil, err 104 | } 105 | return out, nil 106 | } 107 | 108 | // RandomServiceServer is the server API for RandomService service. 109 | type RandomServiceServer interface { 110 | DoSomething(context.Context, *Random) (*Random, error) 111 | } 112 | 113 | func RegisterRandomServiceServer(s *grpc.Server, srv RandomServiceServer) { 114 | s.RegisterService(&_RandomService_serviceDesc, srv) 115 | } 116 | 117 | func _RandomService_DoSomething_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 118 | in := new(Random) 119 | if err := dec(in); err != nil { 120 | return nil, err 121 | } 122 | if interceptor == nil { 123 | return srv.(RandomServiceServer).DoSomething(ctx, in) 124 | } 125 | info := &grpc.UnaryServerInfo{ 126 | Server: srv, 127 | FullMethod: "/pb.RandomService/DoSomething", 128 | } 129 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 130 | return srv.(RandomServiceServer).DoSomething(ctx, req.(*Random)) 131 | } 132 | return interceptor(ctx, in, info, handler) 133 | } 134 | 135 | var _RandomService_serviceDesc = grpc.ServiceDesc{ 136 | ServiceName: "pb.RandomService", 137 | HandlerType: (*RandomServiceServer)(nil), 138 | Methods: []grpc.MethodDesc{ 139 | { 140 | MethodName: "DoSomething", 141 | Handler: _RandomService_DoSomething_Handler, 142 | }, 143 | }, 144 | Streams: []grpc.StreamDesc{}, 145 | Metadata: "random.proto", 146 | } 147 | 148 | func init() { proto.RegisterFile("random.proto", fileDescriptor_random_2b8f171ebf7b1d7e) } 149 | 150 | var fileDescriptor_random_2b8f171ebf7b1d7e = []byte{ 151 | // 129 bytes of a gzipped FileDescriptorProto 152 | 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0x4a, 0xcc, 0x4b, 153 | 0xc9, 0xcf, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x2a, 0x48, 0x52, 0xf2, 0xe2, 0x62, 154 | 0x0b, 0x02, 0x8b, 0x09, 0x29, 0xc1, 0x64, 0x83, 0x4b, 0x8a, 0x32, 0xf3, 0xd2, 0x25, 0x18, 0x15, 155 | 0x18, 0x35, 0x38, 0x83, 0x50, 0xc4, 0x84, 0x64, 0xb8, 0x38, 0x21, 0x7c, 0xcf, 0xbc, 0x12, 0x09, 156 | 0x26, 0xa0, 0x02, 0xd6, 0x20, 0x84, 0x80, 0x91, 0x05, 0x17, 0x2f, 0xc4, 0xac, 0xe0, 0xd4, 0xa2, 157 | 0xb2, 0xcc, 0xe4, 0x54, 0x21, 0x75, 0x2e, 0x6e, 0x97, 0xfc, 0xe0, 0xfc, 0xdc, 0xd4, 0x92, 0x0c, 158 | 0x90, 0x6e, 0x2e, 0xbd, 0x82, 0x24, 0x3d, 0x88, 0x0a, 0x29, 0x24, 0xb6, 0x12, 0x43, 0x12, 0x1b, 159 | 0xd8, 0x41, 0xc6, 0x80, 0x00, 0x00, 0x00, 0xff, 0xff, 0x67, 0xb0, 0xf0, 0x47, 0xa0, 0x00, 0x00, 160 | 0x00, 161 | } 162 | -------------------------------------------------------------------------------- /pb/random.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package pb; 4 | 5 | message Random { 6 | string randomString = 1; 7 | int32 randomInt = 2; 8 | } 9 | 10 | service RandomService { 11 | rpc DoSomething (Random) returns (Random) {} 12 | } 13 | -------------------------------------------------------------------------------- /random.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | context "context" 5 | "log" 6 | 7 | "github.com/Bimde/grpc-vs-rest/pb" 8 | "google.golang.org/grpc" 9 | ) 10 | 11 | func random(c context.Context, input *pb.Random) (*pb.Random, error) { 12 | conn, err := grpc.Dial("sever_address:port") 13 | if err != nil { 14 | log.Fatalf("Dial failed: %v", err) 15 | } 16 | 17 | client := pb.NewRandomServiceClient(conn) 18 | return client.DoSomething(c, &pb.Random{}) 19 | } 20 | -------------------------------------------------------------------------------- /rest_grpc_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "io/ioutil" 7 | "log" 8 | "net/http" 9 | "sync" 10 | "testing" 11 | 12 | "github.com/Bimde/grpc-vs-rest/pb" 13 | "golang.org/x/net/context" 14 | "golang.org/x/net/http2" 15 | "google.golang.org/grpc" 16 | ) 17 | 18 | func BenchmarkHTTP2GetWithWokers(b *testing.B) { 19 | client.Transport = &http2.Transport{ 20 | TLSClientConfig: createTLSConfigWithCustomCert(), 21 | } 22 | requestQueue := make(chan Request) 23 | defer startWorkers(&requestQueue, noWorkers, startPostWorker)() 24 | b.ResetTimer() // don't count worker initialization time 25 | for i := 0; i < b.N; i++ { 26 | requestQueue <- Request{ 27 | Path: "https://bimde:8080", 28 | Random: &pb.Random{ 29 | RandomInt: 2019, 30 | RandomString: "a_string", 31 | }, 32 | } 33 | } 34 | } 35 | 36 | func BenchmarkGRPCWithWokers(b *testing.B) { 37 | conn, err := grpc.Dial("bimde:9090", grpc.WithInsecure()) 38 | if err != nil { 39 | log.Fatalf("Dial failed: %v", err) 40 | } 41 | client := pb.NewRandomServiceClient(conn) 42 | requestQueue := make(chan Request) 43 | defer startWorkers(&requestQueue, noWorkers, getStartGRPCWorkerFunction(client))() 44 | b.ResetTimer() // don't count worker initialization time 45 | 46 | for i := 0; i < b.N; i++ { 47 | requestQueue <- Request{ 48 | Path: "http://localhost:9090", 49 | Random: &pb.Random{ 50 | RandomInt: 2019, 51 | RandomString: "a_string", 52 | }, 53 | } 54 | } 55 | } 56 | 57 | func post(path string, input interface{}, output interface{}) error { 58 | data, err := json.Marshal(input) 59 | if err != nil { 60 | log.Println("error marshalling input ", err) 61 | return err 62 | } 63 | body := bytes.NewBuffer(data) 64 | 65 | req, err := http.NewRequest("POST", path, body) 66 | if err != nil { 67 | log.Println("error creating request ", err) 68 | return err 69 | } 70 | 71 | res, err := client.Do(req) 72 | if err != nil { 73 | log.Println("error executing request ", err) 74 | return err 75 | } 76 | 77 | bytes, err := ioutil.ReadAll(res.Body) 78 | if err != nil { 79 | log.Println("error reading response body ", err) 80 | return err 81 | } 82 | 83 | err = json.Unmarshal(bytes, output) 84 | if err != nil { 85 | log.Println("error unmarshalling response ", err) 86 | return err 87 | } 88 | 89 | return nil 90 | } 91 | 92 | func getStartGRPCWorkerFunction(client pb.RandomServiceClient) func(*chan Request, *sync.WaitGroup) { 93 | return func(requestQueue *chan Request, wg *sync.WaitGroup) { 94 | go func() { 95 | for { 96 | request := <-*requestQueue 97 | if request.Path == stopRequestPath { 98 | wg.Done() 99 | return 100 | } 101 | client.DoSomething(context.TODO(), request.Random) 102 | } 103 | }() 104 | } 105 | } 106 | 107 | func startPostWorker(requestQueue *chan Request, wg *sync.WaitGroup) { 108 | go func() { 109 | for { 110 | request := <-*requestQueue 111 | if request.Path == stopRequestPath { 112 | wg.Done() 113 | return 114 | } 115 | post(request.Path, request.Random, request.Random) 116 | } 117 | }() 118 | } 119 | -------------------------------------------------------------------------------- /restserver/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/Bimde/grpc-vs-rest/restserver 2 | 3 | go 1.12 4 | 5 | require github.com/Bimde/grpc-vs-rest/pb v0.0.0-20190511165804-4eb8cce79d5b 6 | -------------------------------------------------------------------------------- /restserver/go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | github.com/Bimde/grpc-vs-rest/pb v0.0.0-20190511165804-4eb8cce79d5b h1:J7y7JOEqFEM39mN2fsCkgWHqsfxv5z2bO/8TkyNpFHI= 3 | github.com/Bimde/grpc-vs-rest/pb v0.0.0-20190511165804-4eb8cce79d5b/go.mod h1:imKC554J18WtRMRaEfmlRZWPhBByETTbgZR7cYAsklw= 4 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 5 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 6 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 7 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 8 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 9 | github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= 10 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 11 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 12 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 13 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 14 | golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 h1:6M3SDHlHHDCx2PcQw3S4KsR170vGqDhJDOmpVd4Hjak= 15 | golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 16 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 17 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 18 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= 19 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 20 | golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= 21 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 22 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 23 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 24 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= 25 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 26 | google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU= 27 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= 28 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 29 | -------------------------------------------------------------------------------- /restserver/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "log" 6 | "net/http" 7 | 8 | "github.com/Bimde/grpc-vs-rest/pb" 9 | ) 10 | 11 | func handle(w http.ResponseWriter, req *http.Request) { 12 | decoder := json.NewDecoder(req.Body) 13 | var random pb.Random 14 | if err := decoder.Decode(&random); err != nil { 15 | panic(err) 16 | } 17 | random.RandomString = "[Updated] " + random.RandomString 18 | 19 | bytes, err := json.Marshal(&random) 20 | if err != nil { 21 | panic(err) 22 | } 23 | 24 | w.Header().Set("Content-Type", "application/json") 25 | w.Write(bytes) 26 | } 27 | 28 | func main() { 29 | server := &http.Server{Addr: "bimde:8080", Handler: http.HandlerFunc(handle)} 30 | log.Fatal(server.ListenAndServeTLS("../server/server.crt", "../server/server.key")) 31 | } 32 | -------------------------------------------------------------------------------- /server/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/Bimde/grpc-vs-rest/server 2 | 3 | go 1.12 4 | 5 | require github.com/Bimde/grpc-vs-rest/pb v0.0.0-20190510020245-d0b8e3a579ad 6 | -------------------------------------------------------------------------------- /server/go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | github.com/Bimde/grpc-vs-rest/pb v0.0.0-20190510020245-d0b8e3a579ad h1:q7kzkDjKWY6tjnu504+QMb/2ClnM+keD4nyfd8JFE6I= 3 | github.com/Bimde/grpc-vs-rest/pb v0.0.0-20190510020245-d0b8e3a579ad/go.mod h1:imKC554J18WtRMRaEfmlRZWPhBByETTbgZR7cYAsklw= 4 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 5 | github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= 6 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= 7 | github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= 8 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 9 | github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg= 10 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 11 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 12 | golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 13 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 14 | golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5 h1:6M3SDHlHHDCx2PcQw3S4KsR170vGqDhJDOmpVd4Hjak= 15 | golang.org/x/net v0.0.0-20190509222800-a4d6f7feada5/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 16 | golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 17 | golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 18 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= 19 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 20 | golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= 21 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 22 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 23 | google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= 24 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc= 25 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 26 | google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU= 27 | google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= 28 | honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= 29 | -------------------------------------------------------------------------------- /server/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "log" 6 | "net/http" 7 | 8 | "github.com/Bimde/grpc-vs-rest/pb" 9 | ) 10 | 11 | func handle(w http.ResponseWriter, _ *http.Request) { 12 | random := pb.Random{RandomString: "a_random_string", RandomInt: 1984} 13 | bytes, err := json.Marshal(&random) 14 | 15 | if err != nil { 16 | panic(err) 17 | } 18 | 19 | w.Header().Set("Content-Type", "application/json") 20 | w.Write(bytes) 21 | } 22 | 23 | func main() { 24 | server := &http.Server{Addr: "bimde:8080", Handler: http.HandlerFunc(handle)} 25 | log.Fatal(server.ListenAndServeTLS("server.crt", "server.key")) 26 | } 27 | -------------------------------------------------------------------------------- /server/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDhTCCAm2gAwIBAgIUTIwuCEtv+ILvtvYoX+PKRF+hlt0wDQYJKoZIhvcNAQEL 3 | BQAwUjELMAkGA1UEBhMCQ0ExEDAOBgNVBAgMB09udGFyaW8xITAfBgNVBAoMGElu 4 | dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEOMAwGA1UEAwwFYmltZGUwHhcNMTkwNTEw 5 | MDIzODU0WhcNMjAwNTA5MDIzODU0WjBSMQswCQYDVQQGEwJDQTEQMA4GA1UECAwH 6 | T250YXJpbzEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMQ4wDAYD 7 | VQQDDAViaW1kZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALmDiTFK 8 | 9ZkIZ6mUAsaDRfYf23hRt1xEgJcfmPOy7yOYwBuAmHmym0hti6WVMdMuKiBjb6WQ 9 | 8oHEWxBPEVy+HxgmrF7ia/SX+XENiU4raYHHE/+wdXQ1QhrI1FJXxyL7jzPx4Zqg 10 | R1KLcc5w8httWgsRQk9o9Q0N+f0qDPMCejPRACUMHU6bUDhpDNkvlL7FNyAxJscq 11 | PuaKOFkykNiafhKoKlzIPdf/eRib1tKebQwXkF/nsZK/bvF6we9uDHSAnbdlhSht 12 | lyF7HPxH9KtrRXfDXszygLh742FXUkwK9ln5ZnO+FLXvwNoeldbXaZp3wOEdTY0P 13 | 8ZV3Nj0mHHosj0sCAwEAAaNTMFEwHQYDVR0OBBYEFPrjo56g23bkKakQlIUGRE8e 14 | 1hppMB8GA1UdIwQYMBaAFPrjo56g23bkKakQlIUGRE8e1hppMA8GA1UdEwEB/wQF 15 | MAMBAf8wDQYJKoZIhvcNAQELBQADggEBALRSzvIMukaxX8CmyxjKbt95uQQpI69z 16 | CEAOGF1LBcb7YkFHKe2yCh5VYhAWeH/xeAusgA4crs5mklM9y4k8JWxhkqwmN+Ux 17 | xHyGyJXxT4eXzFChW94ljBp0j0hvws0LZzh5AuAKSwzV/uK3v29yX9qQJRV+7aIc 18 | KfGp/cddj0e8/HOcgJ/+BKEa+X+bGKI20gEX14cmWmhdVP6EAiSA0FDASc3N/cNz 19 | Xxb2ozm1qnQZYZIu+TqPoXvTscdcdWLNKaHHaQxIN0r9vjjokCORc9yDi84zogZ+ 20 | C13QSiaRzdpsu1BU2Qjw22uVA0UEGkTIVuBHf74soMl2mz+MEu3iu8I= 21 | -----END CERTIFICATE----- 22 | -------------------------------------------------------------------------------- /server/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC5g4kxSvWZCGep 3 | lALGg0X2H9t4UbdcRICXH5jzsu8jmMAbgJh5sptIbYullTHTLiogY2+lkPKBxFsQ 4 | TxFcvh8YJqxe4mv0l/lxDYlOK2mBxxP/sHV0NUIayNRSV8ci+48z8eGaoEdSi3HO 5 | cPIbbVoLEUJPaPUNDfn9KgzzAnoz0QAlDB1Om1A4aQzZL5S+xTcgMSbHKj7mijhZ 6 | MpDYmn4SqCpcyD3X/3kYm9bSnm0MF5Bf57GSv27xesHvbgx0gJ23ZYUobZchexz8 7 | R/Sra0V3w17M8oC4e+NhV1JMCvZZ+WZzvhS178DaHpXW12mad8DhHU2ND/GVdzY9 8 | Jhx6LI9LAgMBAAECggEABlRSjff8wSfkQYjnP1ajQG590nEXTHKZ4I4XbdkhB5ni 9 | lA2jJiPN4H68UP3yIT5l+Yzq9j8nxv2oDbpk4UErVmubXfFjtYip3g2ULbKVevQL 10 | 3qFqoHhgtQE9HUIZbTwf+qm6BMiLJmnTjDOWTxFADTidhpASLEvZx6Vzo6bl/HaK 11 | JhEMPgfdrLgSyCQzT/68yfTlWQQDj7rqLgPcOkSFoaiQidUR7UYnWR0JPRKv9Ihl 12 | UqvDh89+BmWulvVhNKP2SWrKZ0zh4bfrdbf4YFtu8XL5M/uNVw5hFTcJw6/ekvPt 13 | fW0h118qEcV1tz2vm8goN4u85+ciQbzCwKRfPIGSAQKBgQDgrOaAGzQ8Jo9S0bsu 14 | zJgfx2amf81kyiKtaJS/pZtlJVOZMjGOirXskXJJJ0XI0KjrPRkFhTzIqLgIiWKn 15 | vvQBz12qYQcrjs+S5OVImsn18H9QmLlhIaEPMPvzTrtwlgIkSdE5sdc3FHqXVtCR 16 | 1TnrAjC5yTupaqfb9TwKNQiGwQKBgQDTYOIHjZvHELwEMbQeBhd6L9byF5Qy/BBP 17 | wavB18bHnk9HKQfUINsb9BzrT039n692h+Rm8w99xHGNXG5LSkC12isjWvH2fsWC 18 | HlHyGG/uVvXmBeH1ncGgByBpNekjcFShuPd49Gj5aEVBSDlZqcpt8p8hUOBmSvrN 19 | hsFTqG0FCwKBgApkFLkCCRVrFx/WcVjFv5dgqn+y03YA3z+z4YVHjHtOEaK5Lo+Q 20 | HL/XLjjx5wlVlSpkBf86XUhOfUxvxi9J5pEa3RMfL6y1CyaZDX2hIwwL1meM2K4E 21 | VyWTt2NWVdbsKScyfsmzTufOO6k6K6VC/k2/KS++fdLlCuRiYCd8smtBAoGAfoD/ 22 | BTI0xqA3RfNRLp7Ksi+rXlvKL/E2+eSYnHw81P7jx1zA+K1pNIOWQyXFMUK+Shvu 23 | D8brwIMuykFFKP4ZWDxnkNM++BzKq6LlvBPv+R5GMBHZN5vgY5ugRBclnjX+EIOY 24 | Z+UuZgWHXRiSahz5r2+C2PeENPQuwY4iaaTlCh0CgYAyl93nEMC5cjMAh4O23Y6C 25 | IKD17slXqsc7kRLEvkBTEpsuoHJaThF5wFokwb6sAWnzZJgg4m9TGomsIsKSd1Cr 26 | 4k3kMN/yiOqLZnMZMtuSU2uG8e3rIMvkv5uRFbHvSXgXwQKe3zEuQBtJLqMQHXFz 27 | fNlilUz+/3p7+O9OEULB3g== 28 | -----END PRIVATE KEY----- 29 | --------------------------------------------------------------------------------