Skip to content

Commit

Permalink
feat: skeleton
Browse files Browse the repository at this point in the history
  • Loading branch information
Bastien Rigaud committed Feb 18, 2024
1 parent a42acd8 commit 3016352
Show file tree
Hide file tree
Showing 19 changed files with 140 additions and 88 deletions.
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
run:
air -c .air.toml
cd src && air -c .air.toml

update:
cd src && go mod tidy

test:
cd src/tests/integration && go test -v
6 changes: 3 additions & 3 deletions .air.toml → src/.air.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ tmp_dir = "tmp"

[build]
args_bin = []
bin = "./tmp/main"
cmd = "go build -o ./tmp/main src/cmd/main.go"
bin = "tmp/main"
cmd = "go build -o tmp/main cmd/main.go"
delay = 1000
exclude_dir = ["assets", "tmp", "vendor", "testdata"]
exclude_file = []
Expand All @@ -28,7 +28,7 @@ tmp_dir = "tmp"
stop_on_error = false

[color]
app = ""
app = "magenta"
build = "yellow"
main = "magenta"
runner = "green"
Expand Down
54 changes: 26 additions & 28 deletions src/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,59 +2,57 @@ package main

import (
"context"
"errors"
"fmt"
"net/http"
"os"
"os/signal"
"syscall"

"github.com/Golerplate/user-store-svc/src/internal/config"
handler_user_v1 "github.com/Golerplate/user-store-svc/src/internal/handler/user/v1"
server_user_v1 "github.com/Golerplate/user-store-svc/src/internal/server/user/v1"
"github.com/Golerplate/user-store-svc/src/internal/service"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"

serviceDatastore "github.com/Golerplate/user-store-svc/src/internal/service/datastore/planetscale"
"github.com/Golerplate/user-store-svc/internal/config"
handlers_grpc "github.com/Golerplate/user-store-svc/internal/handlers/grpc"
"github.com/Golerplate/user-store-svc/internal/service"
serviceDatastore "github.com/Golerplate/user-store-svc/internal/service/datastore/planetscale"
)

func main() {
ctx, cancel := context.WithCancel(context.Background())

sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGTERM)

cfg := config.GetServiceConfig()
cfg, err := config.GetServiceConfig()
if err != nil {
panic(err)
}

zerolog.SetGlobalLevel(zerolog.InfoLevel)

userStoreServiceDatastore := serviceDatastore.NewPlanetScaleDatastore()
userStoreService := service.NewUserStoreService(userStoreServiceDatastore)
userStoreServiceHandler := handler_user_v1.NewUserStoreServiceHandler(userStoreService)

grpcBuilder := server_user_v1.NewGRPCBuilder(userStoreServiceHandler)
grpcServer, err := handlers_grpc.NewServer(ctx, cfg.GRPCServerConfig, userStoreService)
if err != nil {
log.Fatal().Err(err).
Msg("main: unable to create gRPC server")
}

grpcServer := http.Server{
Addr: fmt.Sprintf(":%d", cfg.GRPCServerConfig.Port),
Handler: h2c.NewHandler(grpcBuilder, &http2.Server{}),
if err := grpcServer.Setup(ctx); err != nil {
log.Fatal().Err(err).
Msg("main: unable to setup gRPC server")
}

go func() {
if err := grpcServer.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
log.Fatal().Err(err).Msg("unable to start grpc server")
}
}()
if err := grpcServer.Start(ctx); err != nil {
log.Fatal().Err(err).
Msg("main: unable to start gRPC server")
}

<-sigs

log.Info().Msg("caught SIGTERM, exiting")
cancel()

if err := grpcServer.Shutdown(ctx); err != nil {
log.Error().Err(err).Msg("unable to stop grpc server")
if err := grpcServer.Stop(ctx); err != nil {
log.Fatal().Err(err).
Msg("main: unable to stop gRPC server")
}

log.Info().Msg("work done; exiting")

os.Exit(0)
}
2 changes: 1 addition & 1 deletion go.mod → src/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/Golerplate/user-store-svc
go 1.21.5

require (
github.com/Golerplate/contracts v0.0.1
github.com/Golerplate/contracts v0.0.2
github.com/Golerplate/pkg v0.0.2
github.com/bufbuild/connect-go v1.10.0
github.com/bufbuild/connect-grpcreflect-go v1.1.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum → src/go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
github.com/Golerplate/contracts v0.0.1 h1:OtKvpCKVQGTjLFbxYPBkHn/ZC5wQoaumfTlpNuvSmO4=
github.com/Golerplate/contracts v0.0.1/go.mod h1:ALtjMgMcSLE6wGcB2zGIWand81y0HsU+MIvn1mmBP+0=
github.com/Golerplate/contracts v0.0.2 h1:nII6q/QV2QjeTYw4g21G8eT2lzIA6ZXGFHKGQkGiL2k=
github.com/Golerplate/contracts v0.0.2/go.mod h1:ALtjMgMcSLE6wGcB2zGIWand81y0HsU+MIvn1mmBP+0=
github.com/Golerplate/pkg v0.0.2 h1:b1T2Rky4BaJ5c9bHeh0cVII8M1LWcvKfzDJkGmT/G5w=
github.com/Golerplate/pkg v0.0.2/go.mod h1:xj+tuGKV3MtOpy/B6SMBJ0EkbaXMaivufhce/SzwqRk=
github.com/bufbuild/connect-go v1.10.0 h1:QAJ3G9A1OYQW2Jbk3DeoJbkCxuKArrvZgDt47mjdTbg=
Expand Down
7 changes: 3 additions & 4 deletions src/internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package config
import (
"github.com/Golerplate/pkg/grpc"
"github.com/caarlos0/env/v8"
"github.com/rs/zerolog/log"
)

type Config struct {
Expand All @@ -15,11 +14,11 @@ type GeneralConfig struct {
Environment string `env:"ENVIRONMENT" envDefault:"local"`
}

func GetServiceConfig() *Config {
func GetServiceConfig() (*Config, error) {
var cfg Config
if err := env.Parse(&cfg); err != nil {
log.Fatal().Err(err).Msg("unable to build config")
return nil, err
}

return &cfg
return &cfg, nil
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package entity_user_v1
package entities_user_v1

import "time"

Expand Down
74 changes: 74 additions & 0 deletions src/internal/handlers/grpc/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package handlers_grpc

import (
"context"
"fmt"
"net/http"

"github.com/Golerplate/contracts/generated/services/servicesconnect"
"github.com/Golerplate/contracts/generated/services/user/store/v1/storev1connect"
"github.com/Golerplate/pkg/grpc"
pkghandlers "github.com/Golerplate/pkg/grpc/handlers"
sharedmidlewares "github.com/Golerplate/pkg/grpc/interceptors"
"github.com/Golerplate/user-store-svc/internal/handlers"
handlers_grpc_user_v1 "github.com/Golerplate/user-store-svc/internal/handlers/grpc/user/v1"
"github.com/Golerplate/user-store-svc/internal/service"
connectgo "github.com/bufbuild/connect-go"
grpcreflect "github.com/bufbuild/connect-grpcreflect-go"
"github.com/rs/zerolog/log"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
)

type grpcServer struct {
grpcServer *http.Server
config grpc.GRPCServerConfig
service service.UserStoreService
}

func NewServer(ctx context.Context, cfg grpc.GRPCServerConfig, service service.UserStoreService) (handlers.Server, error) {
return &grpcServer{
config: cfg,
service: service,
}, nil
}

func (s *grpcServer) Setup(ctx context.Context) error {
log.Info().
Msg("handlers.grpc.grpcServer.Setup: Setting up gRPC server...")

userStoreServiceHandler := handlers_grpc_user_v1.NewUserStoreServiceHandler(s.service)

interceptors := connectgo.WithInterceptors(sharedmidlewares.ServerDefaultChain()...)

reflector := grpcreflect.NewStaticReflector(
"services.user.store.v1.UserStoreSvc", "services.health.HealthService",
)

mux := http.NewServeMux()
mux.Handle(servicesconnect.NewHealthServiceHandler(pkghandlers.NewHealthHandler()))
mux.Handle(storev1connect.NewUserStoreSvcHandler(userStoreServiceHandler, interceptors))
mux.Handle(grpcreflect.NewHandlerV1(reflector))
mux.Handle(grpcreflect.NewHandlerV1Alpha(reflector))

s.grpcServer = &http.Server{
Addr: fmt.Sprintf(":%d", s.config.Port),
Handler: h2c.NewHandler(mux, &http2.Server{}),
}

return nil
}

func (s *grpcServer) Start(ctx context.Context) error {
log.Info().
Msg("handlers.grpc.grpcServer.Start: Starting gRPC server...")

return s.grpcServer.ListenAndServe()
}

func (s *grpcServer) Stop(ctx context.Context) error {
log.Info().
Msg("handlers.grpc.grpcServer.Stop: Stopping gRPC server...")

return s.grpcServer.Shutdown(ctx)
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package handler_user_v1
package handlers_grpc_user_v1

import (
"github.com/Golerplate/contracts/generated/services/user/store/v1/storev1connect"
"github.com/Golerplate/user-store-svc/src/internal/service"
"github.com/Golerplate/user-store-svc/internal/service"
)

type handler struct {
userStoreService service.UserStoreService
}

func NewUserStoreServiceHandler(userStoreService service.UserStoreService) storev1connect.UserStoreServiceHandler {
func NewUserStoreServiceHandler(userStoreService service.UserStoreService) storev1connect.UserStoreSvcHandler {
return &handler{
userStoreService: userStoreService,
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package handler_user_v1
package handlers_grpc_user_v1

import (
"context"
"errors"

userv1 "github.com/Golerplate/contracts/generated/services/user/store/v1"
"github.com/Golerplate/pkg/grpc"
entity_user_v1 "github.com/Golerplate/user-store-svc/src/internal/entity/user/v1"
entities_user_v1 "github.com/Golerplate/user-store-svc/internal/entities/user/v1"
connectgo "github.com/bufbuild/connect-go"
"github.com/golang/protobuf/ptypes/wrappers"
"google.golang.org/protobuf/types/known/timestamppb"
Expand All @@ -24,7 +24,7 @@ func (h *handler) CreateUser(ctx context.Context, c *connectgo.Request[userv1.Cr
return nil, connectgo.NewError(connectgo.CodeInvalidArgument, errors.New("invalid password"))
}

user, err := h.userStoreService.CreateUser(ctx, &entity_user_v1.CreateUserRequest{
user, err := h.userStoreService.CreateUser(ctx, &entities_user_v1.CreateUserRequest{
Username: c.Msg.GetUsername().GetValue(),
Email: c.Msg.GetEmail().GetValue(),
Password: c.Msg.GetPassword().GetValue(),
Expand Down
1 change: 1 addition & 0 deletions src/internal/handlers/grpc/user/v1/user_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package handlers_grpc_user_v1
9 changes: 9 additions & 0 deletions src/internal/handlers/interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package handlers

import "context"

type Server interface {
Setup(context.Context) error
Start(context.Context) error
Stop(context.Context) error
}
30 changes: 0 additions & 30 deletions src/internal/server/user/v1/server.go

This file was deleted.

4 changes: 2 additions & 2 deletions src/internal/service/datastore/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package datastore
import (
"context"

entity_user_v1 "github.com/Golerplate/user-store-svc/src/internal/entity/user/v1"
entities_user_v1 "github.com/Golerplate/user-store-svc/internal/entities/user/v1"
)

type UserStoreServiceDatastore interface {
CreateUser(ctx context.Context, req *entity_user_v1.CreateUserRequest) (*entity_user_v1.User, error)
CreateUser(ctx context.Context, req *entities_user_v1.CreateUserRequest) (*entities_user_v1.User, error)
}
2 changes: 1 addition & 1 deletion src/internal/service/datastore/planetscale/init.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package planetscale

import (
"github.com/Golerplate/user-store-svc/src/internal/service/datastore"
"github.com/Golerplate/user-store-svc/internal/service/datastore"
_ "github.com/go-sql-driver/mysql"
)

Expand Down
4 changes: 2 additions & 2 deletions src/internal/service/datastore/planetscale/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package planetscale
import (
"context"

entity_user_v1 "github.com/Golerplate/user-store-svc/src/internal/entity/user/v1"
entities_user_v1 "github.com/Golerplate/user-store-svc/internal/entities/user/v1"
)

func (d *dbClient) CreateUser(ctx context.Context, req *entity_user_v1.CreateUserRequest) (*entity_user_v1.User, error) {
func (d *dbClient) CreateUser(ctx context.Context, req *entities_user_v1.CreateUserRequest) (*entities_user_v1.User, error) {
return nil, nil
}
4 changes: 1 addition & 3 deletions src/internal/service/init.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package service

import (
"github.com/Golerplate/user-store-svc/src/internal/service/datastore"
)
import "github.com/Golerplate/user-store-svc/internal/service/datastore"

type service struct {
store datastore.UserStoreServiceDatastore
Expand Down
4 changes: 2 additions & 2 deletions src/internal/service/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package service
import (
"context"

entity_user_v1 "github.com/Golerplate/user-store-svc/src/internal/entity/user/v1"
entities_user_v1 "github.com/Golerplate/user-store-svc/internal/entities/user/v1"
)

type UserStoreService interface {
CreateUser(ctx context.Context, req *entity_user_v1.CreateUserRequest) (*entity_user_v1.User, error)
CreateUser(ctx context.Context, req *entities_user_v1.CreateUserRequest) (*entities_user_v1.User, error)
}
4 changes: 2 additions & 2 deletions src/internal/service/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package service
import (
"context"

entity_user_v1 "github.com/Golerplate/user-store-svc/src/internal/entity/user/v1"
entities_user_v1 "github.com/Golerplate/user-store-svc/internal/entities/user/v1"
)

func (s *service) CreateUser(ctx context.Context, req *entity_user_v1.CreateUserRequest) (*entity_user_v1.User, error) {
func (s *service) CreateUser(ctx context.Context, req *entities_user_v1.CreateUserRequest) (*entities_user_v1.User, error) {
return s.store.CreateUser(ctx, req)
}

0 comments on commit 3016352

Please sign in to comment.