Go Package Layout
Broadly speaking, it is divided into 3 main package folders
cmd
contains main programinternal
app business logicpkg
for packages that can be imported by other go projects / repos
Service Package Design
user_service_repo
cmd/ <- boleh import package /internal & /pkg
api/ <- bisa run echo http & grpc di port yg sama, run /internal/{grpc,http}
main.go
pubsubworker/ <- bisa run multiple pubsub subscription worker, run /internal/worker
main.go
internal/ <-- boleh import /pkg, tidak boleh diimport secara go-module dari repo luar
service/ <- boleh import repository, api_client, tidak boleh import /internal/http & internal/grpc
user_password_service.go
...
service.go
http/ <- expose /internal/service functions. Request/response body struct define di /pkg/http
handler/
user_password_handler.go
...
handler.go
my_custom_middleware.go
my_custom2_middleware.go
...
server.go
grpc/ <- expose /internal/service functions
user_password_handler.go
server.go
worker/ <- import repository, api_client
pubsub_worker.go
user_updated_event_worker.go
new_oba_created_event_worker.go
...
repository/ <- group by datasource / host url instance
userpostgres/ <- should be generated from sqlc
user_password_query.sql.go
user_profile_query.sql.go
...
marketplacepostgres/ <- also should be generated from sqlc
user_email.sql.go
user_address.sql.go
...
registrationmongo/
user_registration_repository.go
...
membermongo/
officer_attribute_repository.go
...
redis/
redis_repository.go
user_cart_repository.go
...
sessionredis/
redis_repository.go
user_session_repository.go
...
...
config/
config_keys.go <- define constant config keys here
config.go <- contains httpClient, db, redis or pubsub connection
constructor
...
pkg/ <- tidak boleh import /internal, boleh diimport secara gomodule dari repo luar
pb/
user.proto
user.pb.go <-- generated
user_validation.go
...
http/
http_api_request.go
http_api_response.go
http_api_client.go
...
Package Descriptions
/cmd
/cmd/api/main.go
-> run gRPC & echo HTTP on the same runtime, different ports. Or choose one as needed. But don't make 2 main programs for gRPC & http unless absolutely necessary for scaling / traffic problems tall./cmd/pubsubworker/main.go
-> run pubsub subscription worker. Can subscribe multiple subscriptions at the same time (with different goroutines). No need to create main programs for different workers unless necessary for scaling / high throughput problems.
The point is, we avoid premature-optimization & make the program more maintainable in terms of development, deployment & operation.
/internal
internal
packages for program logic needed internally by services, and
not intended to be imported by other go programs by gomodule
.
/internal/service
core logic of application gRPC api / JSON webservice/internal/http
implementation ofecho.Echo
http server, router & handler (if required). Implement refer to echo HTTP API design/internal/worker
logic for GCP Pubsub / other messaging./internal/repository
data access layer logic. Implementation refer to- repository design
/internal/apiclient
logic regarding data access via API to third party systems third. Can pass http JSON API, SOAP, gRPC etc./internal/config
contains constant config keys, constructor of dependency services.
/pkg
/pkg/pb
contains definition of .proto file, generated .pb.go, & validation protobuff struct/pkg/http
contains the definition of the request/response body (go/json struct). Can also include api-client if needed (remember, communication between internal services use gRPC)