Skip to content

Commit c4d96be

Browse files
committed
init
0 parents  commit c4d96be

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+4257
-0
lines changed

.idea/go-api-codebase.iml

+9
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules.xml

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/vcs.xml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/workspace.xml

+45
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Dockerfile

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
FROM alpine:latest
2+
3+
# Set the Current Working Directory inside the container
4+
WORKDIR /app
5+
6+
# Build Args
7+
ARG LOG_DIR=/app/logs
8+
9+
# Create Log Directory
10+
RUN mkdir -p ${LOG_DIR}
11+
12+
# Environment Variables
13+
ENV LOG_FILE_LOCATION=${LOG_DIR}/app.log
14+
15+
# Copy the source from the current directory to the Working Directory inside the container
16+
# Copy binary file
17+
COPY main .
18+
# Copy config file
19+
COPY app/config/config.yaml .
20+
21+
# Declare volumes to mount
22+
VOLUME [${LOG_DIR}]
23+
24+
# Command to run the executable
25+
CMD ["./main", "--config", "./config.yaml"]

Makefile

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
postgres:
2+
docker run --name postgres12 -p 5432:5432 -e POSTGRES_USER=root -e POSTGRES_PASSWORD=secret -d postgres:12-alpine
3+
4+
createdb:
5+
docker exec -it postgres12 createdb --username=root --owner=root simple_bank
6+
7+
dropdb:
8+
docker exec -it postgres12 dropdb simple_bank
9+
10+
migrateup:
11+
migrate -path db/migration -database "postgresql://root:secret@localhost:5432/simple_bank?sslmode=disable" -verbose up
12+
13+
migratedown:
14+
migrate -path db/migration -database "postgresql://root:secret@localhost:5432/simple_bank?sslmode=disable" -verbose down
15+
16+
build:
17+
export CGO_ENABLED=0 && go build -o main .
18+
19+
docker_build:
20+
make build && docker build -t api-codebase-go:latest .
21+
22+
docker_run:
23+
docker-compose up
24+
25+
.PHONY: postgres createdb dropdb migrateup migratedown build docker_build docker_run

README.md

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# codebase_go_api
2+
- Install go-migrate: https://github.com/golang-migrate/migrate/tree/master/cmd/migrate
3+
- Install postgres and create db
4+
```
5+
make posgres
6+
make createdb
7+
make migrateup
8+
```
9+
10+
- Run
11+
```
12+
make docker_build // build docker with binary file
13+
make docker_run // run docker-compose
14+
```
15+
- Test
16+
```
17+
curl -d '{"owner": "cathy", "balance": 150, "currency": "EUR"}' -H "Content-Type: application/json" -X POST http://localhost:8000/api/v1/account/add
18+
```
19+
- Update config in file /config/config.yaml
20+
21+
### References
22+
1. [go-database-sql](http://go-database-sql.org/retrieving.html)

app/app.go

+131
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package app
2+
3+
import (
4+
"context"
5+
"github.com/belito3/go-api-codebase/app/config"
6+
"github.com/belito3/go-api-codebase/app/service"
7+
"github.com/belito3/go-api-codebase/app/util"
8+
"github.com/belito3/go-api-codebase/pkg/logger"
9+
"go.uber.org/dig"
10+
"os"
11+
"os/signal"
12+
"sync/atomic"
13+
"syscall"
14+
"time"
15+
)
16+
17+
type options struct {
18+
ConfigFile string
19+
Version string
20+
}
21+
22+
// Option
23+
type Option func(*options)
24+
25+
// SetConfigFile
26+
func SetConfigFile(s string) Option {
27+
return func(o *options) {
28+
o.ConfigFile = s
29+
}
30+
}
31+
32+
// SetVersion
33+
func SetVersion(s string) Option {
34+
return func(o *options) {
35+
o.Version = s
36+
}
37+
}
38+
39+
// Run server
40+
func Run(ctx context.Context, opts ...Option) error {
41+
var state int32 = 1
42+
sc := make(chan os.Signal, 1)
43+
// kill (no param) default send syscall.SIGTERM
44+
// kill -2 is syscall.SIGINT
45+
// kill -9 is syscall.SIGKILL but can't be catch, so don't need add it
46+
// SIGHUP: (signal hang up) sent to a process when its controlling terminal is closed, such as daemons
47+
// SIGINT: Ctrl-C sends an INT signal ("interrupt")
48+
// SIGTERM: signal is sent to a proc ess to request its termination, allows process releasing releasing resources and saving state
49+
// SIGKILL: sent to a process to cause it to terminate immediately (kill), can't perform any clean-up upon receiving this signal
50+
// SIGQUIT: when user requests that the process quit and perform a core dump
51+
signal.Notify(sc, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
52+
cleanFunc, err := Init(ctx, opts...)
53+
if err != nil {
54+
return err
55+
}
56+
57+
EXIT:
58+
for {
59+
sig := <- sc
60+
logger.Printf(ctx, "Received a signal[%s]", sig.String())
61+
switch sig {
62+
case syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGINT:
63+
atomic.CompareAndSwapInt32(&state, 1, 0)
64+
break EXIT
65+
case syscall.SIGHUP:
66+
default:
67+
break EXIT
68+
}
69+
}
70+
71+
cleanFunc()
72+
logger.Printf(ctx, "Service exit")
73+
time.Sleep(time.Second)
74+
os.Exit(int(atomic.LoadInt32(&state)))
75+
return nil
76+
}
77+
78+
// Init
79+
func Init(ctx context.Context, opts ...Option) (func(), error) {
80+
var o options
81+
for _, opt := range opts {
82+
opt(&o)
83+
}
84+
85+
// Init global config
86+
config.Init(o.ConfigFile)
87+
config.PrintWithJSON()
88+
logger.Printf(ctx, "Service started, running mode:%s,version number:%s,process number:%d", config.C.RunMode, o.Version, os.Getpid())
89+
90+
// Initialize trace_id for node that app is running
91+
// TODO: uuid, object, snowflake
92+
util.InitID()
93+
94+
// Init logger
95+
setupLogger()
96+
97+
container, containerCall := BuildContainer()
98+
99+
httpServerCleanFunc := InitHTTPServer(ctx, container)
100+
101+
return func() {
102+
httpServerCleanFunc()
103+
containerCall()
104+
}, nil
105+
}
106+
107+
108+
func BuildContainer() (*dig.Container, func()) {
109+
container := dig.New()
110+
111+
// store DB
112+
storeCall, err := InitStore(container)
113+
handleError(err)
114+
115+
// register service
116+
err = service.Inject(container)
117+
handleError(err)
118+
119+
return container, func() {
120+
if storeCall != nil {
121+
storeCall()
122+
}
123+
}
124+
}
125+
126+
func handleError(err error) {
127+
if err != nil {
128+
panic(err)
129+
}
130+
}
131+

0 commit comments

Comments
 (0)