diff --git a/docs/2022-07-10-bootstrap-go.html b/docs/2022-07-10-bootstrap-go.html index d791a58..1c8665e 100644 --- a/docs/2022-07-10-bootstrap-go.html +++ b/docs/2022-07-10-bootstrap-go.html @@ -46,7 +46,17 @@ func NewS(opts ...OptionS) *S { } return s } -
In above example, I construct s
with WithA
and WithB
option.
No need to pass direct field inside s
.
vendor
Only need if you need something from vendor
, to generate mock or something else.
What is the point to pass many params (do-it
, --abc
, --xyz
) when what we only need is start service?
In my case, service starts with only config, and config should be read from file or environment like The Twelve Factors guide.
Just don't.
Use protocolbuffers/protobuf-go, grpc/grpc-go for gRPC.
Write 1 for both gRPC, REST sounds good, but in the end, it is not worth it.
prototool is deprecated, and buf can generate, lint, format as good as prototool.
Don't use gin.Context
when pass context from handler layer to service layer, use gin.Context.Request.Context()
instead.
It is fast!
Don't overuse func (*Logger) With
. Because if log line is too long, there is a possibility that we can lost it.
Use MarshalLogObject
when we need to hide some field of object when log (field is long or has sensitive value)
Don't use Panic
. Use Fatal
for errors when start service to check dependencies. If you really need panic level, use DPanic
.
If doubt, use zap.Any
.
Use contextID
or traceID
in every log lines for easily debug.
Each ORM libs has each different syntax.
To learn and use those libs correctly is time consuming.
So just stick to plain SQL.
It is easier to debug when something is wrong.
But database/sql
has its own limit.
For example, it is hard to get primary key after insert/update.
So may be you want to use ORM for those cases.
It is easy to write a suite test, thanks to testify.
Also, for mocking, there are many options out there.
Pick 1 then sleep peacefully.
go fmt
, goimports
with mvdan/gofumpt.gofumpt
provides more rules when format Go codes.
No need to say more.
Lint or get the f out!
If you get fieldalignment
error, use fieldalignment to fix them.
# Install
+
In above example, I construct s
with WithA
and WithB
option.
No need to pass direct field inside s
.
vendor
Only need if you need something from vendor
, to generate mock or something else.
build.go
to include build tools in go.modTo easily control version of build tools.
For example build.go
:
//go:build tools
+// +build tools
+
+package main
+
+import (
+ _ "github.com/golang/protobuf/protoc-gen-go"
+)
+
And then in Makefile
:
build:
+ go install github.com/golang/protobuf/protoc-gen-go
+
We always get the version of build tools in go.mod
each time we install it.
Future contributors will not cry anymore.
What is the point to pass many params (do-it
, --abc
, --xyz
) when what we only need is start service?
In my case, service starts with only config, and config should be read from file or environment like The Twelve Factors guide.
Just don't.
Use protocolbuffers/protobuf-go, grpc/grpc-go for gRPC.
Write 1 for both gRPC, REST sounds good, but in the end, it is not worth it.
prototool is deprecated, and buf can generate, lint, format as good as prototool.
Don't use gin.Context
when pass context from handler layer to service layer, use gin.Context.Request.Context()
instead.
It is fast!
Don't overuse func (*Logger) With
. Because if log line is too long, there is a possibility that we can lost it.
Use MarshalLogObject
when we need to hide some field of object when log (field is long or has sensitive value)
Don't use Panic
. Use Fatal
for errors when start service to check dependencies. If you really need panic level, use DPanic
.
If doubt, use zap.Any
.
Use contextID
or traceID
in every log lines for easily debug.
Each ORM libs has each different syntax.
To learn and use those libs correctly is time consuming.
So just stick to plain SQL.
It is easier to debug when something is wrong.
But database/sql
has its own limit.
For example, it is hard to get primary key after insert/update.
So may be you want to use ORM for those cases.
It is easy to write a suite test, thanks to testify.
Also, for mocking, there are many options out there.
Pick 1 then sleep peacefully.
go fmt
, goimports
with mvdan/gofumpt.gofumpt
provides more rules when format Go codes.
No need to say more.
Lint or get the f out!
If you get fieldalignment
error, use fieldalignment to fix them.
# Install
go install golang.org/x/tools/go/analysis/passes/fieldalignment@latest
# Fix
diff --git a/posts/2022-07-10-bootstrap-go.md b/posts/2022-07-10-bootstrap-go.md
index b73a9e7..6d71a14 100644
--- a/posts/2022-07-10-bootstrap-go.md
+++ b/posts/2022-07-10-bootstrap-go.md
@@ -111,6 +111,33 @@ No need to pass direct field inside `s`.
Only need if you need something from `vendor`, to generate mock or something else.
+### Use `build.go` to include build tools in go.mod
+
+To easily control version of build tools.
+
+For example `build.go`:
+
+```go
+//go:build tools
+// +build tools
+
+package main
+
+import (
+ _ "github.com/golang/protobuf/protoc-gen-go"
+)
+```
+
+And then in `Makefile`:
+
+```Makefile
+build:
+ go install github.com/golang/protobuf/protoc-gen-go
+```
+
+We always get the version of build tools in `go.mod` each time we install it.
+Future contributors will not cry anymore.
+
### Don't use cli libs ([spf13/cobra](https://github.com/spf13/cobra), [urfave/cli](https://github.com/urfave/cli)) just for Go service
What is the point to pass many params (`do-it`, `--abc`, `--xyz`) when what we only need is start service?