28/05/2021 - DOCKER, GO
Protocol buffer dosyaları oluşturmak için normal olarak ana bilgisayar işletim sisteminize protobuf ve protoc paketleri kurabilirsiniz. Ancak, bu çözümdeki sorun, her mühendisin komutları kullanmaya başlamadan önce kurulumdan geçmesi gerektiğidir. İşletim sisteminin Linux, Windows veya Mac olabileceği göz önüne alındığında, protocol buffer dosyaları oluşturulduktan sonra diğer sorunların yanı sıra kesinlikle sürüm farklılıkları olacaktır. Bu örnek, her şeyin yapılma şeklini standartlaştırmaktadır. Tek yapmanız gereken, sizin için tüm dosyaları oluşturacak olan docker komutunu çalıştırmak. Ayrıca işletim sisteminize Docker dışında hiçbir şey yüklemezsiniz. Burada Dockerfile
ve docker-compose.yaml
dosyalarına dikkat edin. *.pb.go
dosyaları, make proto-compile
komutunu çalıştırdıktan sonra eklenecek/güncellenecektir. Uygulamanızda çalıştırmanız gereken tek şey go get -u google.golang.org/grpc
komutudur.
├── Makefile
├── cmd
│ ├── client
│ │ └── main.go
│ └── server
│ └── main.go
├── docker
│ ├── Dockerfile
│ └── docker-compose.yaml
├── go.mod
├── go.sum
└── protobuf
├── league.pb.go
├── league.proto
├── team.pb.go
└── team.proto
services:
protogen:
build:
context: "."
args:
PLATFORM: ${PLATFORM}
working_dir: "/source"
volumes:
- "../protobuf:/source"
command: bash -c "protoc --go_out=plugins=grpc:. --go_opt=paths=source_relative *.proto"
FROM golang:1.18.2-buster
ARG PLATFORM
RUN apt-get update && apt-get install -y unzip
# By default Intel chipset (x86_64) is assumed but if the host device is an Apple
# silicon (arm) chipset based then a relevant (aarch_64) release file is used.
RUN export ZIP=x86_64 && \
if [ ${PLATFORM} = "arm64" ]; then export ZIP=aarch_64; fi && \
wget --quiet https://github.com/protocolbuffers/protobuf/releases/download/v3.15.8/protoc-3.15.8-linux-${ZIP}.zip && \
unzip -o protoc-3.15.8-linux-${ZIP}.zip -d /usr/local bin/protoc && \
unzip -o protoc-3.15.8-linux-${ZIP}.zip -d /usr/local 'include/*' && \
go install github.com/golang/protobuf/protoc-gen-go@v1.5.2
syntax = "proto3";
package football;
option go_package = "github.com/you/football/protobuf;footballpb";
message CreateLeagueRequest {
string name = 1;
}
message CreateLeagueResponse {
string id = 1;
}
service LeagueService {
rpc CreateLeague(CreateLeagueRequest) returns (CreateLeagueResponse) {}
}
syntax = "proto3";
package football;
option go_package = "github.com/you/football/protobuf;footballpb";
message CreateTeamRequest {
string name = 1;
}
message CreateTeamResponse {
string id = 1;
}
service TeamService {
rpc CreateTeam(CreateTeamRequest) returns (CreateTeamResponse) {}
}
.PHONY: help
help: ## Display available commands.
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
.PHONY: server-run
server-run: ## Run server.
go run --race cmd/server/main.go
.PHONY: client-run
client-run: ## Run client.
go run --race cmd/client/main.go
.PHONY: proto-compile
proto-compile: ## Compile protobuf files.
PLATFORM=$(shell uname -m) docker-compose -f docker/docker-compose.yaml run --rm protogen
.PHONY: docker-config
docker-config: ## Dump docker-compose configuration.
PLATFORM=$(shell uname -m) docker-compose -f docker/docker-compose.yaml config
.PHONY: docker-down
docker-down: ## Clean up docker artefacts.
PLATFORM=$(shell uname -m) docker-compose -f docker/docker-compose.yaml down
@-docker rmi docker_protogen
docker system prune --volumes --force
package main
import (
"context"
"log"
"time"
"google.golang.org/grpc"
footballpb "github.com/you/football/protobuf"
)
func main() {
// Initialise TCP connection.
con, err := grpc.Dial(":50051", grpc.WithInsecure())
if err != nil {
log.Fatalln(err)
}
defer con.Close()
// Initialise league client.
clt := footballpb.NewLeagueServiceClient(con)
// Create league client request.
req := &footballpb.CreateLeagueRequest{Name: "Super League"}
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
// Send create league request.
res, err := clt.CreateLeague(ctx, req)
if err != nil {
log.Fatalln(err)
}
log.Println(res.GetId())
}
package main
import (
"context"
"log"
"net"
"google.golang.org/grpc"
footballpb "github.com/you/football/protobuf"
)
func main() {
// Initialise TCP listener.
lis, err := net.Listen("tcp", ":50051")
if err != nil {
log.Fatal(err)
}
defer lis.Close()
// Initialise GRPC server.
grpcSrv := grpc.NewServer()
footballpb.RegisterLeagueServiceServer(grpcSrv, &LeagueServer{})
log.Fatalln(grpcSrv.Serve(lis))
}
type LeagueServer struct{}
func (l *LeagueServer) CreateLeague(ctx context.Context, req *footballpb.CreateLeagueRequest) (*footballpb.CreateLeagueResponse, error) {
log.Println(req.GetName())
return &footballpb.CreateLeagueResponse{Id: "ID"}, nil
}