grpcdotnetgo

module
v0.1.322 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 20, 2024 License: Apache-2.0

README

gRPC-dot-net-go

Installation

When used with Go modules, use the following import path:

go get github.com/fluffy-bunny/grpcdotnetgo

Stand-Alone Samples

samples

Contracts

It all starts with a proto file. In our case we want to have a custom server implementation that understands that the real downstream hanlder is in our DI. Fortunately we can use a protoc plugin to generate the GO code for that.

cd example
go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.26
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.1
go get -u github.com/fluffy-bunny/grpcdotnetgo/protoc-gen-go-di/cmd/protoc-gen-go-di

protoc --proto_path=. --proto_path=vendor --proto_path=vendor/github.com/fluffy-bunny  --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative --go-di_out=. --go-di_opt=paths=source_relative ./example/internal/grpcContracts/helloworld/helloworld.proto

This will generate all the go files from our helloworld.proto

Generated grpc interfaces
grpc interface
type GreeterServer interface {
	// Sends a greeting
	SayHello(context.Context, *HelloRequest) (*HelloReply, error)
	mustEmbedUnimplementedGreeterServer()
}
grpcdotnetgo inteface
// IGreeterService defines the required downstream service interface
type IGreeterService interface {
	SayHello(request *HelloRequest) (*HelloReply, error)
}

We simplify the interface by removing the context.Context argument. If you still needed it, you can inject the IContextAccessor. This is following the asp.net model where you inject IHttpContextAccessor to get at the request context when a Request comes in.

Scoped Request

In asp.net when a request comes in, a scoped di container is created and is active for the duration of the request. We do the samne thing when a grpc request comes in.
Looking at the IGreeterService, it is up to your application to implement this interface. It also must be registered as a scoped object. In asp.net this is hidden from us, but here we have to do it manually.

import (
	"fmt"

	"github.com/fluffy-bunny/grpcdotnetgo/example/internal"
	pb "github.com/fluffy-bunny/grpcdotnetgo/example/internal/grpcContracts/helloworld"
	contracts_claimsprincipal "github.com/fluffy-bunny/grpcdotnetgo/pkg/contracts/claimsprincipal"
	contracts_logger "github.com/fluffy-bunny/grpcdotnetgo/pkg/contracts/logger"
	contracts_request "github.com/fluffy-bunny/grpcdotnetgo/pkg/contracts/request"
	grpc_error "github.com/fluffy-bunny/grpcdotnetgo/pkg/grpc/error"
	"google.golang.org/grpc/codes"
)

// Service is used to implement helloworld.GreeterServer.
type Service struct {
	Request         contracts_request.IRequest                 `inject:""`
	ClaimsPrincipal contracts_claimsprincipal.IClaimsPrincipal `inject:""`
	Logger          contracts_logger.ILogger                   `inject:""`
	Config          *internal.Config                           `inject:""`
}
// Ctor if it exists is called when the service is created
func (s *Service) Ctor() {
	s.Logger.Info().Msg("Ctor")
}

// Close if it exists is called when the container is torn down
func (s *Service) Close() {
	s.Logger.Info().Msg("Close")
}


// AddScopedIGreeterService adds service to the DI container
func AddScopedIGreeterService(builder *di.Builder) {
	pb.AddScopedIGreeterService(builder, reflect.TypeOf(&Service{}))
}

In asp.net core simply by adding an interface into our constructor, the framwork figures out by type what we need and injects it.

public class MyGreeterService : IGreeterService
{
        private IHttpContextAccessor _httpContextAccessor;
        private ILogger<MyGreeterService> _logger;

        public MyGreeterService(
            IHttpContextAccessor httpContextAccessor,
            ILogger<MyGreeterService> logger)
        {
            _httpContextAccessor = httpContextAccessor;
            _logger = logger;
        }
}

The AddGreeterService func is our CTOR. It is responsible for creating the object and as you can see it pulls the services it needs direct from the DI.

In Summary

We map the go grpc endpoints, GreeterServer to our simpler interface IGreeterService. When a grpc call comes in, we create a scoped container, pull the matching interface IGreeterService and call it after we have made sure that relied upon scoped objects are setup correctly ILogger,IClaimsPrincipal,IContextAccessor etc.

Directories

Path Synopsis
example module
cmd/server
Package main implements a server for Greeter service.
Package main implements a server for Greeter service.
internal/grpcContracts/helloworld
Package helloworld is a reverse proxy.
Package helloworld is a reverse proxy.
internal/mocks/scoped
Package scoped is a generated GoMock package.
Package scoped is a generated GoMock package.
internal/mocks/singleton
Package singleton is a generated GoMock package.
Package singleton is a generated GoMock package.
internal/mocks/transient
Package transient is a generated GoMock package.
Package transient is a generated GoMock package.
internal
pkg
di
echo/mocks/contextaccessor
Package contextaccessor is a generated GoMock package.
Package contextaccessor is a generated GoMock package.
echo/mocks/cookies
Package cookies is a generated GoMock package.
Package cookies is a generated GoMock package.
echo/mocks/handler
Package handler is a generated GoMock package.
Package handler is a generated GoMock package.
go-grpc-middleware/auth
`grpc_auth` a generic server-side auth middleware for gRPC.
`grpc_auth` a generic server-side auth middleware for gRPC.
middleware/context
There be a memory leak when calling WithTimeout and you don't call the cancel func.
There be a memory leak when calling WithTimeout and you don't call the cancel func.
mocks/auth
Package auth is a generated GoMock package.
Package auth is a generated GoMock package.
mocks/backgroundtasks
Package backgroundtasks is a generated GoMock package.
Package backgroundtasks is a generated GoMock package.
mocks/cache
Package cache is a generated GoMock package.
Package cache is a generated GoMock package.
mocks/claimsprincipal
Package claimsprincipal is a generated GoMock package.
Package claimsprincipal is a generated GoMock package.
mocks/core
Package core is a generated GoMock package.
Package core is a generated GoMock package.
mocks/grpc
Package grpc is a generated GoMock package.
Package grpc is a generated GoMock package.
mocks/metadatafilter
Package metadatafilter is a generated GoMock package.
Package metadatafilter is a generated GoMock package.
mocks/oauth2
Package oauth2 is a generated GoMock package.
Package oauth2 is a generated GoMock package.
mocks/oauth2/github
Package github is a generated GoMock package.
Package github is a generated GoMock package.
mocks/oidc
Package oidc is a generated GoMock package.
Package oidc is a generated GoMock package.
mocks/request
Package request is a generated GoMock package.
Package request is a generated GoMock package.
mocks/serviceprovider
Package serviceprovider is a generated GoMock package.
Package serviceprovider is a generated GoMock package.
mocks/timeutils
Package timeutils is a generated GoMock package.
Package timeutils is a generated GoMock package.
mocks/uuid
Package uuid is a generated GoMock package.
Package uuid is a generated GoMock package.
utils
copied and modified from datadog/dd-trace-go/internal/env.go
copied and modified from datadog/dd-trace-go/internal/env.go
protoc-gen-go-di
helloworld
Package helloworld is a reverse proxy.
Package helloworld is a reverse proxy.
pkg

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL