Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add micro service arch #9

Merged
merged 1 commit into from
Jun 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions arch/micro/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package micro

import (
"context"
)

type NatsContext struct {
context.Context
Client *NatsClient
Subject string
}

func NewNatsContext(client *NatsClient, baseSub string) *NatsContext {
return &NatsContext{
Context: context.Background(),
Client: client,
Subject: baseSub,
}
}
24 changes: 24 additions & 0 deletions arch/micro/controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package micro

import (
"github.com/unusualcodeorg/goserve/arch/network"
)

type baseController struct {
network.BaseController
natsCtx *NatsContext
}

func NewBaseController(basePath string, authProvider network.AuthenticationProvider, authorizeProvider network.AuthorizationProvider) BaseController {
return &baseController{
BaseController: network.NewBaseController(basePath, authProvider, authorizeProvider),
}
}

func (c *baseController) SetNatsContext(ctx *NatsContext) {
c.natsCtx = ctx
}

func (c *baseController) NatsContext() *NatsContext {
return c.natsCtx
}
34 changes: 34 additions & 0 deletions arch/micro/interfaces.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package micro

import (
"github.com/nats-io/nats.go/micro"
"github.com/unusualcodeorg/goserve/arch/network"
)

type NatsGroup = micro.Group
type NatsHandlerFunc = micro.HandlerFunc
type NatsRequest = micro.Request

type Config struct {
NatsUrl string
NatsServiceName string
NatsServiceVersion string
}

type BaseController interface {
network.BaseController
SetNatsContext(ctx *NatsContext)
NatsContext() *NatsContext
}

type Controller interface {
BaseController
MountNats(group NatsGroup)
}

type Router interface {
network.BaseRouter
NatsClient() *NatsClient
Disconnect()
LoadControllers(controllers []Controller)
}
19 changes: 19 additions & 0 deletions arch/micro/message.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package micro

type Message[T any] struct {
Data *T `json:"data,omitempty"`
Error *string `json:"error,omitempty"`
}

func NewMessage[T any](data *T, err error) *Message[T] {
var e *string
if err != nil {
er := err.Error()
e = &er
}

return &Message[T]{
Data: data,
Error: e,
}
}
40 changes: 40 additions & 0 deletions arch/micro/nats.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package micro

import (
"fmt"
"time"

"github.com/nats-io/nats.go"
"github.com/nats-io/nats.go/micro"
)

type NatsClient struct {
Conn *nats.Conn
Service micro.Service
Timeout time.Duration
}

func NewNatsClient(config Config) *NatsClient {
fmt.Println("connecting to nats..")

nc, err := nats.Connect(config.NatsUrl)
if err != nil {
panic(err)
}

srv, err := micro.AddService(nc, micro.Config{
Name: config.NatsServiceName,
Version: config.NatsServiceVersion,
})
if err != nil {
panic(err)
}

fmt.Println("connected to nats..")

return &NatsClient{
Conn: nc,
Service: srv,
Timeout: nats.DefaultTimeout,
}
}
37 changes: 37 additions & 0 deletions arch/micro/request.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package micro

import (
"encoding/json"
"errors"
"fmt"
)

func Respond[T any](req NatsRequest, data *T, err error) {
req.RespondJSON(NewMessage(data, err))
}

func Request[T any, V any](ctx *NatsContext, sub string, send *T, receive *V) (*V, error) {
sendMsg := NewMessage(send, nil)
sendPayload, err := json.Marshal(sendMsg)
if err != nil {
return nil, err
}

subject := fmt.Sprintf(`%s.%s`, ctx.Subject, sub)
msg, err := ctx.Client.Conn.Request(subject, sendPayload, ctx.Client.Timeout)
if err != nil {
return nil, err
}

var receiveMsg Message[V]
err = json.Unmarshal(msg.Data, &receiveMsg)
if err != nil {
return nil, err
}

if receiveMsg.Error != nil {
err = errors.New(*receiveMsg.Error)
}

return receiveMsg.Data, err
}
65 changes: 65 additions & 0 deletions arch/micro/router.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package micro

import (
"fmt"
"strings"

"github.com/gin-gonic/gin"
"github.com/go-playground/validator/v10"
"github.com/unusualcodeorg/goserve/arch/network"
)

type router struct {
netRouter network.Router
natsClient *NatsClient
}

func NewRouter(mode string, config Config) Router {
natsClient := NewNatsClient(config)
return &router{
netRouter: network.NewRouter(mode),
natsClient: natsClient,
}
}

func (r *router) GetEngine() *gin.Engine {
return r.netRouter.GetEngine()
}

func (r *router) NatsClient() *NatsClient {
return r.natsClient
}

func (r *router) Disconnect() {
r.natsClient.Conn.Close()
}

func (r *router) LoadRootMiddlewares(middlewares []network.RootMiddleware) {
r.netRouter.LoadRootMiddlewares(middlewares)
}

func (r *router) LoadControllers(controllers []Controller) {
nc := make([]network.Controller, len(controllers))
for i, c := range controllers {
nc[i] = c.(network.Controller)
}
r.netRouter.LoadControllers(nc)

for _, c := range controllers {
baseSub := fmt.Sprintf(`%s.%s`, r.natsClient.Service.Info().Name, strings.ReplaceAll(c.Path(), "/", ""))

ctx := NewNatsContext(r.natsClient, baseSub)
c.SetNatsContext(ctx)

ng := r.natsClient.Service.AddGroup(baseSub)
c.MountNats(ng)
}
}

func (r *router) Start(ip string, port uint16) {
r.netRouter.Start(ip, port)
}

func (r *router) RegisterValidationParsers(tagNameFunc validator.TagNameFunc) {
r.netRouter.RegisterValidationParsers(tagNameFunc)
}
8 changes: 6 additions & 2 deletions arch/network/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,18 @@ type ParamNMiddlewareProvider[T any] interface {
type AuthenticationProvider Param0MiddlewareProvider
type AuthorizationProvider ParamNMiddlewareProvider[string]

type Router interface {
type BaseRouter interface {
GetEngine() *gin.Engine
RegisterValidationParsers(tagNameFunc validator.TagNameFunc)
LoadControllers(controllers []Controller)
LoadRootMiddlewares(middlewares []RootMiddleware)
Start(ip string, port uint16)
}

type Router interface {
BaseRouter
LoadControllers(controllers []Controller)
}

type Module[T any] interface {
GetInstance() *T
RootMiddlewares() []RootMiddleware
Expand Down
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/go-playground/validator/v10 v10.22.0
github.com/golang-jwt/jwt/v5 v5.2.1
github.com/jinzhu/copier v0.4.0
github.com/nats-io/nats.go v1.35.0
github.com/redis/go-redis/v9 v9.5.3
github.com/spf13/viper v1.19.0
github.com/stretchr/testify v1.9.0
Expand Down Expand Up @@ -40,6 +41,8 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/montanaflynn/stats v0.7.1 // indirect
github.com/nats-io/nkeys v0.4.7 // indirect
github.com/nats-io/nuid v1.0.1 // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/sagikazarmark/locafero v0.6.0 // indirect
Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/nats-io/nats.go v1.35.0 h1:XFNqNM7v5B+MQMKqVGAyHwYhyKb48jrenXNxIU20ULk=
github.com/nats-io/nats.go v1.35.0/go.mod h1:Ubdu4Nh9exXdSz0RVWRFBbRfrbSxOYd26oF0wkWclB8=
github.com/nats-io/nkeys v0.4.7 h1:RwNJbbIdYCoClSDNY7QVKZlyb/wfT6ugvFCiKy6vDvI=
github.com/nats-io/nkeys v0.4.7/go.mod h1:kqXRgRDPlGy7nGaEDMuYzmiJCIAAWDK0IMBtDmGD0nc=
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
Expand Down