Skip to content

Commit 1ebdad1

Browse files
committed
feat: add dynamic gin json
add dynamic gin json
0 parents  commit 1ebdad1

File tree

27 files changed

+913
-0
lines changed

27 files changed

+913
-0
lines changed

.dockerignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
bin
2+
data
3+
README.md
4+
.env
5+
docker-compose.yml
6+
Dockerfile

.github/workflows/image.yaml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Image build
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
tags:
8+
- v*
9+
pull_request:
10+
11+
env:
12+
IMAGE_NAME: blog-api
13+
14+
jobs:
15+
16+
push:
17+
runs-on: ubuntu-latest
18+
19+
steps:
20+
- uses: actions/checkout@v4
21+
- name: Build image
22+
run: docker compose build blog-api
23+
- name: Tag with Image
24+
run: docker tag blog-api:latest $IMAGE_NAME:$GITHUB_SHA
25+
- name: Log in to registry
26+
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
27+
- name: Push to registry
28+
run: |
29+
IMAGE_ID=ghcr.io/leetcode-golang-classroom/$IMAGE_NAME
30+
IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]')
31+
VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
32+
[[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
33+
[ "$VERSION" == "main" ] && VERSION=latest
34+
echo IMAGE_ID=$IMAGE_ID
35+
echo VERSION=$VERSION
36+
docker tag $IMAGE_NAME $IMAGE_ID:$VERSION
37+
docker push $IMAGE_ID:$VERSION

.gitignore

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# If you prefer the allow list template instead of the deny list, see community template:
2+
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
3+
#
4+
# Binaries for programs and plugins
5+
*.exe
6+
*.exe~
7+
*.dll
8+
*.so
9+
*.dylib
10+
11+
# Test binary, built with `go test -c`
12+
*.test
13+
14+
# Output of the go coverage tool, specifically when used with LiteIDE
15+
*.out
16+
17+
# Dependency directories (remove the comment below to include it)
18+
# vendor/
19+
20+
# Go workspace file
21+
go.work
22+
go.work.sum
23+
24+
# env file
25+
.env
26+
data
27+
bin

Dockerfile

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
FROM golang:1.22.0 AS build
2+
WORKDIR /app
3+
COPY go.mod go.sum Makefile ./
4+
ADD . ./
5+
RUN go mod download && make build
6+
7+
FROM build AS test
8+
RUN make test
9+
10+
FROM alpine as release
11+
WORKDIR /app
12+
COPY --from=build /app/bin ./bin
13+
COPY --from=build /app/template ./template
14+
CMD ["./bin/main"]

Makefile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
.PHONY=build
2+
3+
build:
4+
@CGO_ENABLED=0 GOOS=linux go build -o bin/main cmd/main.go
5+
6+
run: build
7+
@./bin/main
8+
9+
coverage:
10+
@go test -v -cover ./...
11+
12+
test:
13+
@go test -v ./...

README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# golang-gin-with-dynamic-json
2+
3+
This repository is for use gin framework to serve dynamic web page
4+
5+
## architecture
6+
7+
![architecture](architecture.png)
8+
9+
## handle pagination with gorm middleware format
10+
11+
```golang
12+
func Paginate(ctx *gin.Context) func(db *gorm.DB) *gorm.DB {
13+
return func(db *gorm.DB) *gorm.DB {
14+
pageStr := ctx.DefaultQuery("page", "1")
15+
page, _ := strconv.Atoi(pageStr)
16+
if page <= 0 {
17+
page = 1
18+
}
19+
pageSizeStr := ctx.DefaultQuery("page_size", "10")
20+
pageSize, _ := strconv.Atoi(pageSizeStr)
21+
switch {
22+
case pageSize > 100:
23+
pageSize = 100
24+
case pageSize <= 0:
25+
pageSize = 10
26+
}
27+
dbClone := db.Session(&gorm.Session{})
28+
var total int64
29+
dbClone.Count(&total)
30+
totalPages := int(math.Ceil(float64(total) / float64(pageSize)))
31+
ctx.Set("page", page)
32+
ctx.Set("pageSize", pageSize)
33+
ctx.Set("totalPages", totalPages)
34+
offset := (page - 1) * pageSize
35+
return db.Offset(offset).Limit(pageSize)
36+
}
37+
}
38+
```

cmd/main.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"log"
6+
"os"
7+
"os/signal"
8+
"syscall"
9+
10+
"github.com/leetcode-golang-classroom/golang-gin-with-dynamic-json/internal/application"
11+
"github.com/leetcode-golang-classroom/golang-gin-with-dynamic-json/internal/config"
12+
)
13+
14+
func main() {
15+
app := application.New(config.AppConfig)
16+
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM, syscall.SIGINT)
17+
defer func() {
18+
log.Println("gin-json-http stoping")
19+
cancel()
20+
}()
21+
err := app.Start(ctx)
22+
if err != nil {
23+
log.Println("failed to start gin-json-http:", err)
24+
}
25+
}

docker-compose.yml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
services:
2+
blog-api:
3+
container_name: blog-api
4+
build:
5+
context: .
6+
dockerfile: Dockerfile
7+
target: release
8+
image: blog-api
9+
environment:
10+
PORT: ${PORT}
11+
MYSQL_DATABASE: ${MYSQL_DATABASE}
12+
MYSQL_USER: ${MYSQL_USER}
13+
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
14+
MYSQL_ADDR: db:3306
15+
GIN_MODE: release
16+
ports:
17+
- ${PORT}:${PORT}
18+
networks:
19+
- mysql
20+
depends_on:
21+
db:
22+
condition: service_healthy
23+
logging:
24+
driver: json-file
25+
options:
26+
max-size: 1k
27+
max-file: 3
28+
db:
29+
image: mysql:8
30+
container_name: mysql
31+
restart: always
32+
environment:
33+
MYSQL_DATABASE: ${MYSQL_DATABASE}
34+
MYSQL_USER: ${MYSQL_USER}
35+
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
36+
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
37+
ports:
38+
- ${MYSQL_PORT}:${MYSQL_PORT}
39+
volumes:
40+
- ./data:/var/lib/mysql
41+
logging:
42+
driver: json-file
43+
options:
44+
max-size: 1k
45+
max-file: 3
46+
networks:
47+
- mysql
48+
healthcheck:
49+
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost", "-uroot", "-p${MYSQL_ROOT_PASSWORD}"]
50+
interval: 5s
51+
timeout: 5s
52+
retries: 10
53+
networks:
54+
mysql:
55+
driver: bridge
56+
name: mysql

go.mod

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
module github.com/leetcode-golang-classroom/golang-gin-with-dynamic-json
2+
3+
go 1.21.4
4+
5+
require (
6+
github.com/go-sql-driver/mysql v1.7.0
7+
github.com/spf13/viper v1.19.0
8+
gorm.io/driver/mysql v1.5.7
9+
gorm.io/gorm v1.25.11
10+
)
11+
12+
require (
13+
github.com/bytedance/sonic v1.11.6 // indirect
14+
github.com/bytedance/sonic/loader v0.1.1 // indirect
15+
github.com/cloudwego/base64x v0.1.4 // indirect
16+
github.com/cloudwego/iasm v0.2.0 // indirect
17+
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
18+
github.com/gin-contrib/sse v0.1.0 // indirect
19+
github.com/go-playground/locales v0.14.1 // indirect
20+
github.com/go-playground/universal-translator v0.18.1 // indirect
21+
github.com/go-playground/validator/v10 v10.20.0 // indirect
22+
github.com/goccy/go-json v0.10.2 // indirect
23+
github.com/jinzhu/inflection v1.0.0 // indirect
24+
github.com/jinzhu/now v1.1.5 // indirect
25+
github.com/json-iterator/go v1.1.12 // indirect
26+
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
27+
github.com/leodido/go-urn v1.4.0 // indirect
28+
github.com/mattn/go-isatty v0.0.20 // indirect
29+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
30+
github.com/modern-go/reflect2 v1.0.2 // indirect
31+
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
32+
github.com/ugorji/go/codec v1.2.12 // indirect
33+
golang.org/x/arch v0.8.0 // indirect
34+
golang.org/x/crypto v0.23.0 // indirect
35+
golang.org/x/net v0.25.0 // indirect
36+
google.golang.org/protobuf v1.34.1 // indirect
37+
)
38+
39+
require (
40+
github.com/fsnotify/fsnotify v1.7.0 // indirect
41+
github.com/gin-gonic/gin v1.10.0
42+
github.com/hashicorp/hcl v1.0.0 // indirect
43+
github.com/magiconair/properties v1.8.7 // indirect
44+
github.com/mitchellh/mapstructure v1.5.0 // indirect
45+
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
46+
github.com/sagikazarmark/locafero v0.4.0 // indirect
47+
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
48+
github.com/sourcegraph/conc v0.3.0 // indirect
49+
github.com/spf13/afero v1.11.0 // indirect
50+
github.com/spf13/cast v1.6.0 // indirect
51+
github.com/spf13/pflag v1.0.5 // indirect
52+
github.com/subosito/gotenv v1.6.0 // indirect
53+
go.uber.org/atomic v1.9.0 // indirect
54+
go.uber.org/multierr v1.9.0 // indirect
55+
golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect
56+
golang.org/x/sys v0.20.0 // indirect
57+
golang.org/x/text v0.15.0 // indirect
58+
gopkg.in/ini.v1 v1.67.0 // indirect
59+
gopkg.in/yaml.v3 v3.0.1 // indirect
60+
)

0 commit comments

Comments
 (0)