Different approach to some challenges
(no AI)
Staff Backend Engineer at Pento
I used to hate generated code.
Everyday life with generated code.
Error while building:
# github.com/antosdaniel/go-presentation-generate-code/internal/grpc
internal/grpc/payrollServiceWithAuth.go:16:9: ... (missing method GetPayslip)
Generators are just CLI tools:
go generate <path>
go generate ./...
syntax = "proto3";
package payroll.v1;
service PayrollService {
rpc AddPayroll(AddPayrollRequest) returns (AddPayrollResponse);
rpc AddPayslip(AddPayslipRequest) returns (AddPayslipResponse);
rpc GetPayroll(GetPayrollRequest) returns (GetPayrollResponse);
}
message AddPayrollRequest {
string payroll_id = 1;
string tenant_id = 2;
Date payday = 3;
}
// ...
// PayrollServiceHandler is an implementation of the payroll.v1.PayrollService service.
type PayrollServiceHandler interface {
AddPayroll(context.Context, *connect_go.Request[payrollv1.AddPayrollRequest]) (*connect_go.Response[payrollv1.AddPayrollResponse], error)
AddPayslip(context.Context, *connect_go.Request[payrollv1.AddPayslipRequest]) (*connect_go.Response[payrollv1.AddPayslipResponse], error)
GetPayroll(context.Context, *connect_go.Request[payrollv1.GetPayrollRequest]) (*connect_go.Response[payrollv1.GetPayrollResponse], error)
}
// Now we only have to implement it:
func (s *payrollServiceServer) AddPayroll(
ctx context.Context,
request *connect_go.Request[payrollv1.AddPayrollRequest],
) (*connect_go.Response[payrollv1.AddPayrollResponse], error) {
// TODO: business logic
return &connect_go.Response[payrollv1.AddPayrollResponse]{
Msg: &payrollv1.AddPayrollResponse{ PayrollId: id, },
}, nil
}
create table payrolls (
id uuid not null primary key,
tenant_id uuid not null,
payday date not null
);
type PayrollModel struct {
ID string `orm:"id"`
TenantID string `orm:"tenant_id"`
Payday string `orm:"payday"`
}
func FindPayroll(ctx context.Context, exec boil.ContextExecutor, iD string, selectCols ...string) (*Payroll, error) {
payrollObj := &Payroll{}
sel := "*"
if len(selectCols) > 0 {
sel = strings.Join(strmangle.IdentQuoteSlice(dialect.LQ, dialect.RQ, selectCols), ",")
}
query := fmt.Sprintf(
"select %s from \"payrolls\" where \"id\"=$1", sel,
)
q := queries.Raw(query, iD)
err := q.Bind(ctx, exec, payrollObj)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, sql.ErrNoRows
}
return nil, errors.Wrap(err, "models: unable to select from payrolls")
}
return payrollObj, nil
}
func (ps PayrollServiceWithTrace) AddPayroll(...) error {
ps.tracer.Start(...)
defer ps.tracer.End(...)
err := ps.base.AddPayroll(...)
if err != nil {
ps.tracer.RaiseError(err)
}
return err
}
func (ps PayrollServiceWithTrace) AddPayslip(...) error {
ps.tracer.Start(...)
defer ps.tracer.End(...)
err := ps.base.AddPayslip(...)
if err != nil {
ps.tracer.RaiseError(err)
}
return err
}
because you will hit some issues
.PHONY: install
install:
@printf "\nInstalling sqlboiler...\n"
@go install -mod=readonly github.com/volatiletech/sqlboiler/v4@v4.15.0
@go install -mod=readonly github.com/volatiletech/sqlboiler/v4/drivers/sqlboiler-psql@v4.15.0
@printf "\nInstalling gowrap...\n"
@go install -mod=readonly github.com/hexdigest/gowrap/cmd/gowrap@v1.3.2
# ...
.PHONY: generate
generate:
@printf "Generating protos...\n"
@buf generate --template gen/grpc/buf.gen.yaml
@printf "Generating db models...\n"
@sqlboiler --config db/sqlboiler.toml psql
@printf "go generate...\n"
@go generate ./...
@$(MAKE) format
Any questions for me?