From 268ee5791396d3947af61913a80c9498ace1e446 Mon Sep 17 00:00:00 2001 From: Alexander Date: Mon, 4 May 2026 14:56:05 +0200 Subject: [PATCH] Grpc hello service implementation --- .gitignore | 3 +++ api/Hello Echo.bru | 23 +++++++++++++++++ api/Hello Ping.bru | 21 +++++++++++++++ api/bruno.json | 23 +++++++++++++++++ api/collection.bru | 0 buf.gen.yaml | 8 ++++++ buf.yaml | 9 +++++++ cmd/music-agregator/main.go | 23 +++++++++++++++++ flake.nix | 5 ++++ go.mod | 10 +++++--- go.sum | 8 ++++++ internal/hello/server.go | 27 ++++++++++++++++++++ justfile | 9 +++++-- proto/music_agregator/hello/v1/service.proto | 22 ++++++++++++++++ 14 files changed, 186 insertions(+), 5 deletions(-) create mode 100644 api/Hello Echo.bru create mode 100644 api/Hello Ping.bru create mode 100644 api/bruno.json create mode 100644 api/collection.bru create mode 100644 buf.gen.yaml create mode 100644 buf.yaml create mode 100644 internal/hello/server.go create mode 100644 proto/music_agregator/hello/v1/service.proto diff --git a/.gitignore b/.gitignore index c2d5f5e..1215215 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,6 @@ bin/ # Ignore config.yaml config.yaml + +# Ignore protobuf generated files +gen/ diff --git a/api/Hello Echo.bru b/api/Hello Echo.bru new file mode 100644 index 0000000..6e7a5ac --- /dev/null +++ b/api/Hello Echo.bru @@ -0,0 +1,23 @@ +meta { + name: Hello Echo + type: grpc + seq: 3 +} + +grpc { + url: localhost:8081 + method: /music_agregator.hello.v1.HelloService/Echo + body: grpc + protoPath: ../proto/music_agregator/hello/v1/service.proto + auth: none + methodType: unary +} + +body:grpc { + name: message 1 + content: ''' + { + "msg": "hello" + } + ''' +} diff --git a/api/Hello Ping.bru b/api/Hello Ping.bru new file mode 100644 index 0000000..cd050ee --- /dev/null +++ b/api/Hello Ping.bru @@ -0,0 +1,21 @@ +meta { + name: Hello Ping + type: grpc + seq: 1 +} + +grpc { + url: localhost:8081 + method: /music_agregator.hello.v1.HelloService/Ping + body: grpc + protoPath: ../proto/music_agregator/hello/v1/service.proto + auth: none + methodType: unary +} + +body:grpc { + name: message 1 + content: ''' + {} + ''' +} diff --git a/api/bruno.json b/api/bruno.json new file mode 100644 index 0000000..29714da --- /dev/null +++ b/api/bruno.json @@ -0,0 +1,23 @@ +{ + "version": "1", + "name": "Music Agregator", + "type": "collection", + "protobuf": { + "importPaths": [ + { + "path": "../proto", + "enabled": true + } + ], + "protoFiles": [ + { + "path": "../proto/music_agregator/hello/v1/service.proto", + "type": "file" + } + ] + }, + "presets": { + "requestType": "grpc", + "requestUrl": "" + } +} \ No newline at end of file diff --git a/api/collection.bru b/api/collection.bru new file mode 100644 index 0000000..e69de29 diff --git a/buf.gen.yaml b/buf.gen.yaml new file mode 100644 index 0000000..98f0b86 --- /dev/null +++ b/buf.gen.yaml @@ -0,0 +1,8 @@ +version: v2 +plugins: + - remote: buf.build/protocolbuffers/go + out: gen + opt: paths=source_relative + - remote: buf.build/grpc/go + out: gen + opt: paths=source_relative diff --git a/buf.yaml b/buf.yaml new file mode 100644 index 0000000..c7e30e3 --- /dev/null +++ b/buf.yaml @@ -0,0 +1,9 @@ +version: v2 +modules: + - path: proto +lint: + use: + - STANDARD +breaking: + use: + - FILE diff --git a/cmd/music-agregator/main.go b/cmd/music-agregator/main.go index 21d91c1..dea17ce 100644 --- a/cmd/music-agregator/main.go +++ b/cmd/music-agregator/main.go @@ -2,15 +2,19 @@ package main import ( "flag" + "net" "os" "github.com/gin-gonic/gin" "github.com/rs/zerolog" "github.com/rs/zerolog/log" + "google.golang.org/grpc" "gopkg.in/yaml.v2" + pb "homelab.lan/music-agregator/gen/music_agregator/hello/v1" // My modules "homelab.lan/music-agregator/internal/config" + "homelab.lan/music-agregator/internal/hello" appRouter "homelab.lan/music-agregator/internal/router" ) @@ -27,6 +31,14 @@ func main() { } log.Info().Interface("config", cfg).Msg("Loaded config") + // start the grpc in another thread to not block the next http start + go serveGrpc() + + serveHttp() + +} + +func serveHttp() { router := gin.Default() appRouter.SetupRoutes(router) router.GET("/ping", func(c *gin.Context) { @@ -35,7 +47,18 @@ func main() { }) }) router.Run() +} +func serveGrpc() { + var opts []grpc.ServerOption + server := grpc.NewServer(opts...) + helloServiceHandler := hello.NewHelloServer() + pb.RegisterHelloServiceServer(server, helloServiceHandler) + listener, err := net.Listen("tcp", "localhost:8081") + if err != nil { + log.Fatal().Err(err).Msg("Failed to listen on localhost:8081") + } + server.Serve(listener) } func parseConfig(path *string) (config.Config, error) { diff --git a/flake.nix b/flake.nix index c9cfa60..da28464 100644 --- a/flake.nix +++ b/flake.nix @@ -53,7 +53,10 @@ plantuml just + nixd + bruno + buf protobuf protoc-gen-go protoc-gen-go-grpc @@ -62,6 +65,8 @@ gopls gotools go-tools + + opencode ]; }; }; diff --git a/go.mod b/go.mod index 1e51032..77c2079 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,10 @@ require ( github.com/rs/zerolog v1.35.1 ) -require github.com/mattn/go-colorable v0.1.14 // indirect +require ( + github.com/mattn/go-colorable v0.1.14 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect +) require ( github.com/bytedance/gopkg v0.1.3 // indirect @@ -36,8 +39,9 @@ require ( golang.org/x/arch v0.22.0 // indirect golang.org/x/crypto v0.48.0 // indirect golang.org/x/net v0.51.0 // indirect - golang.org/x/sys v0.41.0 // indirect + golang.org/x/sys v0.42.0 // indirect golang.org/x/text v0.34.0 // indirect - google.golang.org/protobuf v1.36.10 // indirect + google.golang.org/grpc v1.81.0 + google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v2 v2.4.0 ) diff --git a/go.sum b/go.sum index 199d68f..c4efd55 100644 --- a/go.sum +++ b/go.sum @@ -89,10 +89,18 @@ golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= +golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.81.0 h1:W3G9N3KQf3BU+YuCtGKJk0CmxQNbAISICD/9AORxLIw= +google.golang.org/grpc v1.81.0/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I= google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= diff --git a/internal/hello/server.go b/internal/hello/server.go new file mode 100644 index 0000000..4936dd8 --- /dev/null +++ b/internal/hello/server.go @@ -0,0 +1,27 @@ +package hello + +import ( + "context" + + pb "homelab.lan/music-agregator/gen/music_agregator/hello/v1" +) + +type HelloServer struct { + pb.UnimplementedHelloServiceServer +} + +func NewHelloServer() *HelloServer { + return &HelloServer{} +} + +func (server *HelloServer) Ping(ctx context.Context, req *pb.PingRequest) (*pb.PongResponse, error) { + return &pb.PongResponse{}, nil +} + +func (server *HelloServer) Echo(ctx context.Context, req *pb.EchoRequest) (*pb.EchoResponse, error) { + response := &pb.EchoResponse{ + Response: req.GetMsg(), + } + + return response, nil +} diff --git a/justfile b/justfile index 7580b87..372da8b 100644 --- a/justfile +++ b/justfile @@ -1,8 +1,13 @@ target := "cmd/music-agregator/main.go" -build: +proto: + buf generate + +build: proto go build {{target}} + tidy: go mod tidy -run *FLAGS: + +run *FLAGS: proto go run {{target}} {{FLAGS}} diff --git a/proto/music_agregator/hello/v1/service.proto b/proto/music_agregator/hello/v1/service.proto new file mode 100644 index 0000000..78b3eae --- /dev/null +++ b/proto/music_agregator/hello/v1/service.proto @@ -0,0 +1,22 @@ +syntax = "proto3"; +package music_agregator.hello.v1; +option go_package = "homelab.lan/music-agregator/gen/music_agregator/v1/hello"; + +service HelloService { + rpc Ping(PingRequest) returns (PongResponse) {} + rpc Echo(EchoRequest) returns (EchoResponse) {} +} + +message PingRequest { + +} +message PongResponse { +} + +message EchoRequest { + string msg = 1; +} + +message EchoResponse { + string response = 1; +}