Loading...
Loading...
Generate Go services following GO modular architechture conventions (Fx DI, OTEL tracing, interface-first design). Use when creating reusable business services in internal/modules/<module>/service/ - email senders, token generators, hashing utilities, template compilers, cache-backed lookups, or any domain service that encapsulates a single responsibility and is consumed by use cases or other services.
npx skill4agent add cristiano-pacheco/ai-rules go-create-serviceinternal/modules/<module>/dto/<service_name>_dto.gointernal/modules/<module>/ports/<service_name>_service.gointernal/modules/<module>/service/<service_name>_service.goXxxServiceXxxServiceNewXxxServiceinternal/modules/<module>/dto/<service_name>_dto.gopackage dto
type DoSomethingInput struct {
Field string
}internal/modules/<module>/ports/<service_name>_service.gopackage ports
import (
"context"
"github.com/cristiano-pacheco/pingo/internal/modules/<module>/dto"
)
type DoSomethingService interface {
Execute(ctx context.Context, input dto.DoSomethingInput) error
}internal/modules/<module>/service/<service_name>_service.gopackage service
import (
"context"
"github.com/cristiano-pacheco/bricks/pkg/logger"
"github.com/cristiano-pacheco/bricks/pkg/otel/trace"
"github.com/cristiano-pacheco/pingo/internal/modules/<module>/dto"
"github.com/cristiano-pacheco/pingo/internal/modules/<module>/ports"
)
type DoSomethingService struct {
logger logger.Logger
// other dependencies
}
var _ ports.DoSomethingService = (*DoSomethingService)(nil)
func NewDoSomethingService(
logger logger.Logger,
) *DoSomethingService {
return &DoSomethingService{
logger: logger,
}
}
func (s *DoSomethingService) Execute(ctx context.Context, input dto.DoSomethingInput) error {
ctx, span := trace.Span(ctx, "DoSomethingService.Execute")
defer span.End()
// Business logic here
return nil
}Executedto/send_email_confirmation_dto.gotype SendEmailConfirmationInput struct {
UserModel model.UserModel
ConfirmationTokenHash []byte
}ports/send_email_confirmation_service.gotype SendEmailConfirmationService interface {
Execute(ctx context.Context, input dto.SendEmailConfirmationInput) error
}ports/hash_service.gotype HashService interface {
GenerateFromPassword(password []byte) ([]byte, error)
CompareHashAndPassword(hashedPassword, password []byte) error
GenerateRandomBytes() ([]byte, error)
}type HashService struct{}
func NewHashService() *HashService {
return &HashService{}
}trace.Spanctx, span := trace.Span(ctx, "ServiceName.MethodName")
defer span.End()"StructName.MethodName"
## Naming
- Port interface: `XxxService` (in `ports` package, no suffix)
- Implementation struct: `XxxService` (in `service` package, same name — disambiguated by package)
- Constructor: `NewXxxService`, returns a pointer of the struct implementation
## Fx Wiring
Add to `internal/modules/<module>/fx.go`:
```go
fx.Provide(
fx.Annotate(
service.NewXxxService,
fx.As(new(ports.XxxService)),
),
),logger.Loggerports.XxxServiceports.XxxRepositoryports.XxxCachedto/ports/service/ports/<name>_service.godto/<name>_dto.govar _ ports.XxxService = (*XxxService)(nil)*XxxServicetrace.Spandefer span.End()context.Contextdto/<name>_dto.goports/<name>_service.goservice/<name>_service.gomodule.gofx.gomake lintmake nilaway