feat: stop using global var
parent
971b11a16c
commit
31462cc014
|
@ -15,7 +15,7 @@ internal
|
|||
| | service.go
|
||||
| | repository.go
|
||||
| | models.go
|
||||
</code></pre><p>All business codes are inside <code>internal</code>.<br>Each business has a different directory <code>business</code>.<p>Inside each business, there are 2 handlers: <code>http</code>, <code>grpc</code>:<ul><li><code>http</code> is for public APIs (Android, iOS, ... are clients).<li><code>grpc</code> is for internal APIs (other services are clients).<li><code>consumer</code> is for consuming messages from queue (Kafka, RabbitMQ, ...).</ul><p>For each handler, there are usually 3 layers: <code>handler</code>, <code>service</code>, <code>repository</code>:<ul><li><code>handler</code> 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.<li><code>service</code> is where we write business/logic codes, and only business/logic codes is written here.<li><code>repository</code> is where we write codes which interacts with database/cache like MySQL, Redis, ...<li><code>models</code> is where we put all request, response, data models.</ul><p>Location:<ul><li><code>handler</code> must exist inside <code>grpc</code>, <code>http</code>, <code>consumer</code>.<li><code>service</code>, <code>models</code> can exist directly inside of <code>business</code> if both <code>grpc</code>, <code>http</code>, <code>consumer</code> has same business/logic.<li><code>repository</code> should be placed directly inside of <code>business</code>.</ul><h2>Do not repeat!</h2><p>If we have too many services, some of the logic will be overlapped.<p>For example, service A and service B both need to make POST call API to service C.<br>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.<br>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.<p>Another bad practice is adapter service.<br>No need to write a new service if what we need is just common pkg libs.<h2>Taste on style guide</h2><h3>Use functional options, but don't overuse it!</h3><p>For simple struct with 1 or 2 fields, no need to use functional options.<p><a href=https://go.dev/play/p/0XnOLiHuoz3>Example</a>:<pre><code class=language-go>func main() {
|
||||
</code></pre><p>All business codes are inside <code>internal</code>.<br>Each business has a different directory <code>business</code>.<p>Inside each business, there are 2 handlers: <code>http</code>, <code>grpc</code>:<ul><li><code>http</code> is for public APIs (Android, iOS, ... are clients).<li><code>grpc</code> is for internal APIs (other services are clients).<li><code>consumer</code> is for consuming messages from queue (Kafka, RabbitMQ, ...).</ul><p>For each handler, there are usually 3 layers: <code>handler</code>, <code>service</code>, <code>repository</code>:<ul><li><code>handler</code> 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.<li><code>service</code> is where we write business/logic codes, and only business/logic codes is written here.<li><code>repository</code> is where we write codes which interacts with database/cache like MySQL, Redis, ...<li><code>models</code> is where we put all request, response, data models.</ul><p>Location:<ul><li><code>handler</code> must exist inside <code>grpc</code>, <code>http</code>, <code>consumer</code>.<li><code>service</code>, <code>models</code> can exist directly inside of <code>business</code> if both <code>grpc</code>, <code>http</code>, <code>consumer</code> has same business/logic.<li><code>repository</code> should be placed directly inside of <code>business</code>.</ul><h2>Do not repeat!</h2><p>If we have too many services, some of the logic will be overlapped.<p>For example, service A and service B both need to make POST call API to service C.<br>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.<br>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.<p>Another bad practice is adapter service.<br>No need to write a new service if what we need is just common pkg libs.<h2>Taste on style guide</h2><h3>Stop using global var</h3><p>If I see someone using global var, I swear I shoot twice in the face.<p>Why?<ul><li>Can not write unit test.<li>Is not thread safe.</ul><h3>Use functional options, but don't overuse it!</h3><p>For simple struct with 1 or 2 fields, no need to use functional options.<p><a href=https://go.dev/play/p/0XnOLiHuoz3>Example</a>:<pre><code class=language-go>func main() {
|
||||
s := NewS(WithA(1), WithB("b"))
|
||||
fmt.Printf("%+v\n", s)
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue