diff --git a/docs/2022-07-10-bootstrap-go.html b/docs/2022-07-10-bootstrap-go.html index 1c8665e..ea67cc9 100644 --- a/docs/2022-07-10-bootstrap-go.html +++ b/docs/2022-07-10-bootstrap-go.html @@ -15,7 +15,7 @@ internal | | service.go | | repository.go | | models.go -
All business codes are inside internal
.
Each business has a different directory business
.
Inside each business, there are 2 handlers: http
, grpc
:
http
is for public APIs (Android, iOS, ... are clients).grpc
is for internal APIs (other services are clients).consumer
is for consuming messages from queue (Kafka, RabbitMQ, ...).For each handler, there are usually 3 layers: handler
, service
, repository
:
handler
interacts directly with gRPC, REST or consumer using specific codes (cookies, ...) In case gRPC, there are frameworks outside handle for us so we can write business/logic codes here too. But remember, gRPC only.service
is where we write business/logic codes, and only business/logic codes is written here.repository
is where we write codes which interacts with database/cache like MySQL, Redis, ...models
is where we put all request, response, data models.Location:
handler
must exist inside grpc
, http
, consumer
.service
, models
can exist directly inside of business
if both grpc
, http
, consumer
has same business/logic.repository
should be placed directly inside of business
.If we have too many services, some of the logic will be overlapped.
For example, service A and service B both need to make POST call API to service C.
If service A and service B both have libs to call service C to do that API, we need to move the libs to some common pkg libs.
So in the future, service D which needs to call C will not need to copy libs to handle service C api but only need to import from common pkg libs.
Another bad practice is adapter service.
No need to write a new service if what we need is just common pkg libs.
For simple struct with 1 or 2 fields, no need to use functional options.
func main() {
+
All business codes are inside internal
.
Each business has a different directory business
.
Inside each business, there are 2 handlers: http
, grpc
:
http
is for public APIs (Android, iOS, ... are clients).grpc
is for internal APIs (other services are clients).consumer
is for consuming messages from queue (Kafka, RabbitMQ, ...).For each handler, there are usually 3 layers: handler
, service
, repository
:
handler
interacts directly with gRPC, REST or consumer using specific codes (cookies, ...) In case gRPC, there are frameworks outside handle for us so we can write business/logic codes here too. But remember, gRPC only.service
is where we write business/logic codes, and only business/logic codes is written here.repository
is where we write codes which interacts with database/cache like MySQL, Redis, ...models
is where we put all request, response, data models.Location:
handler
must exist inside grpc
, http
, consumer
.service
, models
can exist directly inside of business
if both grpc
, http
, consumer
has same business/logic.repository
should be placed directly inside of business
.If we have too many services, some of the logic will be overlapped.
For example, service A and service B both need to make POST call API to service C.
If service A and service B both have libs to call service C to do that API, we need to move the libs to some common pkg libs.
So in the future, service D which needs to call C will not need to copy libs to handle service C api but only need to import from common pkg libs.
Another bad practice is adapter service.
No need to write a new service if what we need is just common pkg libs.
If I see someone using global var, I swear I shoot twice in the face.
Why?
For simple struct with 1 or 2 fields, no need to use functional options.
func main() {
s := NewS(WithA(1), WithB("b"))
fmt.Printf("%+v\n", s)
}
diff --git a/posts/2022-07-10-bootstrap-go.md b/posts/2022-07-10-bootstrap-go.md
index 6d71a14..6dc1d41 100644
--- a/posts/2022-07-10-bootstrap-go.md
+++ b/posts/2022-07-10-bootstrap-go.md
@@ -62,6 +62,15 @@ No need to write a new service if what we need is just common pkg libs.
## Taste on style guide
+### Stop using global var
+
+If I see someone using global var, I swear I shoot twice in the face.
+
+Why?
+
+- Can not write unit test.
+- Is not thread safe.
+
### Use functional options, but don't overuse it!
For simple struct with 1 or 2 fields, no need to use functional options.