Skip to content

Commit 22b5e1d

Browse files
committed
release(main): create boilerplate app
0 parents  commit 22b5e1d

24 files changed

+727
-0
lines changed

.dockerignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
docker-compose.yml
2+
Dockerfile
3+
.env*

.env.example

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
POSTGRES_DB=
2+
POSTGRES_PASSWORD=
3+
POSTGRES_USER=
4+
DB_HOST=db
5+
DB_PORT=5432
6+
BASE_URL=http://localhost:8000
7+
APP_SECRET=

.gitignore

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# BINARIES
2+
build/
3+
artifacts/
4+
bin/
5+
dist/
6+
*.exe
7+
*.out
8+
9+
# DEPENDENCIES
10+
/vendor/
11+
/go/pkg/
12+
13+
# LOCAL
14+
.env
15+
.local
16+
17+
# IDE
18+
.idea/
19+
.vscode/
20+
21+
# LOG
22+
*.log
23+
24+
# OTHERS
25+
.DS_Store
26+
Thumbs.db
27+
*.cover
28+
*.cov

Dockerfile

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
FROM golang:alpine3.21 AS builder
2+
3+
WORKDIR /app
4+
5+
COPY . .
6+
7+
RUN go mod download \
8+
&& CGO_ENABLED=0 GOOS=linux go build -o main ./
9+
10+
# Build a minimal image
11+
FROM alpine:latest
12+
13+
# Add a non-root user
14+
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
15+
USER appuser
16+
17+
WORKDIR /app
18+
19+
COPY --from=builder /app/main /usr/local/bin/main
20+
21+
EXPOSE 8000
22+
23+
CMD ["main"]

README.md

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# Gin Boilerplate API
2+
3+
`gin-boilerplate-api` is a Go-based microservice designed to handle client-related operations. This API provides endpoints for managing user data and authentication.
4+
5+
## Table of Contents
6+
7+
- [Features](#features)
8+
- [Getting Started](#getting-started)
9+
- [API Endpoints](#api-endpoints)
10+
- [Examples](#examples)
11+
12+
## Features
13+
14+
- RESTful API for client management.
15+
- Built with Go for high performance and scalability.
16+
- Easy to integrate with other microservices.
17+
18+
## Getting Started
19+
20+
1. Clone the repository:
21+
```bash
22+
git clone https://github.com/mathleite/gin-boilerplate-api-api.git
23+
```
24+
2. Navigate to the project directory:
25+
```bash
26+
cd gin-boilerplate-api-api
27+
```
28+
3. Create and fill .env:
29+
```bash
30+
cp .env.example .env && \
31+
vim .env
32+
```
33+
4. Run the application:
34+
```bash
35+
docker compose up --build --no-cache -d
36+
```
37+
38+
## API Endpoints
39+
40+
### Base URL
41+
42+
```
43+
http://localhost:8000/api/v1
44+
```
45+
46+
### Endpoints
47+
48+
- **GET /health**: Application _health-check_.
49+
- **POST /register**: Register a user.
50+
- **POST /signin**: SignIn a user.
51+
- **GET /transactions**: Access a authenticated endpoint _(has no logic here)_.
52+
53+
## Examples
54+
55+
### Create a User
56+
57+
**Request:**
58+
59+
```bash
60+
curl --request POST \
61+
--url http://localhost:8000/api/v1/register \
62+
--header 'Content-Type: application/json' \
63+
--data '{
64+
"name": "Boiler Plate",
65+
"email": "me.boilerplate@devlocal.com",
66+
"password": "123root"
67+
}'
68+
```
69+
70+
### SignIn
71+
72+
**Request:**
73+
74+
```bash
75+
curl --request POST \
76+
--url http://localhost:8000/api/v1/auth/signin \
77+
--header 'Content-Type: application/json' \
78+
--data '{
79+
"email": "me.matheusleite@devlocal.com",
80+
"password": "123root"
81+
}'
82+
```
83+
84+
**Response:**
85+
86+
```json
87+
{
88+
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NDEzMDUxMTcsImlhdCI6MTc0MTMwMzMxNywidXNlcl9pZCI6ImRiNGI5YWE4LTMwZDMtNDExMy05MjE2LTUwZTE0MTQ2OGQ1NSJ9.ZvUjK32lDg6OTFdNl-OTQDV_2ywcYLAWNWu3V23QYgo"
89+
}
90+
```
91+
92+
### "Fetch transactions"
93+
94+
**Request:**
95+
96+
```bash
97+
curl --request GET \
98+
--url http://localhost:8000/api/v1/transactions \
99+
--header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NDEzMDUxMTcsImlhdCI6MTc0MTMwMzMxNywidXNlcl9pZCI6ImRiNGI5YWE4LTMwZDMtNDExMy05MjE2LTUwZTE0MTQ2OGQ1NSJ9.ZvUjK32lDg6OTFdNl-OTQDV_2ywcYLAWNWu3V23QYgo'
100+
```

database/base.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package database
2+
3+
import (
4+
"time"
5+
6+
"github.com/google/uuid"
7+
)
8+
9+
type BaseTable struct {
10+
ID uuid.UUID `gorm:"type:uuid;default:gen_random_uuid();primaryKey" json:"id"`
11+
CreatedAt time.Time `json:"created_at" gorm:"default:now()"`
12+
UpdatedAt time.Time `json:"updated_at" gorm:"default:now()"`
13+
}

database/setup.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package database
2+
3+
import (
4+
"fmt"
5+
"log"
6+
"os"
7+
8+
"gorm.io/driver/postgres"
9+
"gorm.io/gorm"
10+
"gorm.io/gorm/logger"
11+
)
12+
13+
var (
14+
Db *gorm.DB
15+
)
16+
17+
func Setup() {
18+
db, err := gorm.Open(postgres.Open(getDatabaseDns()), &gorm.Config{
19+
Logger: logger.Default.LogMode(logger.Info),
20+
})
21+
if err != nil {
22+
log.Fatalln("Database connection fails:", err)
23+
}
24+
Db = db
25+
log.Println("Database connection successfully.")
26+
migrateDatabase()
27+
}
28+
29+
func getDatabaseDns() string {
30+
host := os.Getenv("DB_HOST")
31+
dbname := os.Getenv("POSTGRES_DB")
32+
port := os.Getenv("DB_PORT")
33+
user := os.Getenv("POSTGRES_USER")
34+
pass := os.Getenv("POSTGRES_PASSWORD")
35+
return fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%s", host, user, pass, dbname, port)
36+
}
37+
38+
func migrateDatabase() {
39+
if err := Db.AutoMigrate(&User{}); err != nil {
40+
log.Fatal("Fail to migrate database: ", err)
41+
}
42+
}

database/user.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package database
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
)
7+
8+
type User struct {
9+
BaseTable
10+
Name string `gorm:"not null" json:"name"`
11+
Email string `gorm:"not null;uniqueIndex" json:"email"`
12+
Password string `gorm:"not null" json:"password"`
13+
}
14+
15+
func (u *User) Save() error {
16+
if err := Db.Create(&u).Error; err != nil {
17+
if strings.Contains(err.Error(), "duplicate key value violates unique constraint") {
18+
return fmt.Errorf("e-mail already exists: %s", u.Email)
19+
}
20+
return fmt.Errorf("fail to save user: %v", err)
21+
}
22+
return nil
23+
}
24+
25+
func (u *User) FindByEmail(email string) (*User, error) {
26+
var user User
27+
if err := Db.Where("email = ?", email).First(&user).Error; err != nil {
28+
return nil, fmt.Errorf("user not found: %v", err)
29+
}
30+
return &user, nil
31+
}

docker-compose.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
services:
2+
db:
3+
image: postgres:13.20-alpine3.20
4+
restart: always
5+
shm_size: 128mb
6+
env_file:
7+
- .env
8+
ports:
9+
- "5432:5432"
10+
networks:
11+
- backend
12+
13+
transaction-api:
14+
build:
15+
context: .
16+
dockerfile: Dockerfile
17+
container_name: transactionApi
18+
working_dir: /app
19+
volumes:
20+
- .:/app
21+
ports:
22+
- "8000:8000"
23+
depends_on:
24+
- db
25+
networks:
26+
- backend
27+
env_file:
28+
- .env
29+
30+
networks:
31+
backend:
32+
driver: bridge

go.mod

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
module github.com/mathleite/gin-boilerplate-api
2+
3+
go 1.23.4
4+
5+
require (
6+
github.com/gin-gonic/gin v1.10.0
7+
github.com/golang-jwt/jwt/v5 v5.2.1
8+
github.com/golodash/galidator/v2 v2.0.1
9+
)
10+
11+
require (
12+
github.com/bytedance/sonic v1.12.9 // indirect
13+
github.com/bytedance/sonic/loader v0.2.3 // indirect
14+
github.com/cloudwego/base64x v0.1.5 // indirect
15+
github.com/dlclark/regexp2 v1.7.0 // indirect
16+
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
17+
github.com/gin-contrib/sse v1.0.0 // indirect
18+
github.com/go-playground/locales v0.14.1 // indirect
19+
github.com/go-playground/universal-translator v0.18.1 // indirect
20+
github.com/go-playground/validator/v10 v10.25.0 // indirect
21+
github.com/goccy/go-json v0.10.5 // indirect
22+
github.com/golang/protobuf v1.5.0 // indirect
23+
github.com/golodash/godash v1.2.0 // indirect
24+
github.com/google/uuid v1.6.0 // indirect
25+
github.com/jackc/pgpassfile v1.0.0 // indirect
26+
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
27+
github.com/jackc/pgx/v5 v5.7.2 // indirect
28+
github.com/jackc/puddle/v2 v2.2.2 // indirect
29+
github.com/jinzhu/copier v0.3.5 // indirect
30+
github.com/jinzhu/inflection v1.0.0 // indirect
31+
github.com/jinzhu/now v1.1.5 // indirect
32+
github.com/json-iterator/go v1.1.12 // indirect
33+
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
34+
github.com/leodido/go-urn v1.4.0 // indirect
35+
github.com/mattn/go-isatty v0.0.20 // indirect
36+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
37+
github.com/modern-go/reflect2 v1.0.2 // indirect
38+
github.com/nyaruka/phonenumbers v1.1.6 // indirect
39+
github.com/pelletier/go-toml/v2 v2.2.3 // indirect
40+
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
41+
github.com/ugorji/go/codec v1.2.12 // indirect
42+
golang.org/x/arch v0.14.0 // indirect
43+
golang.org/x/crypto v0.34.0 // indirect
44+
golang.org/x/net v0.35.0 // indirect
45+
golang.org/x/sync v0.11.0 // indirect
46+
golang.org/x/sys v0.30.0 // indirect
47+
golang.org/x/text v0.22.0 // indirect
48+
google.golang.org/protobuf v1.36.5 // indirect
49+
gopkg.in/yaml.v3 v3.0.1 // indirect
50+
gorm.io/driver/postgres v1.5.11 // indirect
51+
gorm.io/gorm v1.25.12 // indirect
52+
)

0 commit comments

Comments
 (0)