Skip to content

TeamUpLabs/argu-x-server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Argu-X Server

현대적인 Go 웹 서버로, Gin 프레임워크를 기반으로 구축되었으며 JWT 인증, SQLite 데이터베이스, RESTful API 엔드포인트를 제공합니다.

📋 목차

🚀 주요 기능

  • ⚡ 고성능 웹 프레임워크: Gin 웹 프레임워크 기반으로 구축
  • 🔐 JWT 인증 시스템: 안전한 토큰 기반 인증
  • 🗄️ 경량 데이터베이스: GORM ORM과 함께하는 SQLite
  • 🌐 CORS 지원: 크로스 오리진 리소스 공유 활성화
  • 🏥 헬스체크: 내장된 서버 상태 확인 엔드포인트
  • 🛑 그레이스풀 셧다운: 적절한 서버 종료 처리
  • ⚙️ 환경 변수 설정: 환경 변수 기반 설정 관리
  • 📝 구조화된 로깅: 이모지와 함께하는 포괄적인 로깅 시스템
  • 🧩 모듈화 아키텍처: 깔끔한 코드 구조와 분리
  • ⚡ 실시간 업데이트: WebSocket을 통한 실시간 토론 정보 동기화
  • 💬 토론 플랫폼: 찬반 토론을 위한 완전한 플랫폼 (ARGX 토큰 시스템 포함)

💻 기술 스택

Core Technologies

  • Go 1.25.3: 고성능 프로그래밍 언어
  • Gin Web Framework: 경량 웹 프레임워크
  • GORM: Go를 위한 강력한 ORM 라이브러리
  • SQLite: 서버가 필요 없는 관계형 데이터베이스
  • JWT: JSON Web Token 인증

Dependencies

  • CORS Middleware: 크로스 오리진 요청 처리
  • Environment Management: .env 파일 지원
  • Crypto: 비밀번호 해싱 및 보안
  • Logging: 구조화된 로그 관리
  • WebSocket: 실시간 양방향 통신 (gorilla/websocket)

🎯 시작하기

필수 요구사항

  • Go 1.19 이상: Go 다운로드
  • Git: 버전 관리 시스템
  • 텍스트 에디터: VS Code, GoLand 등

시스템 요구사항

  • 운영체제: Windows, macOS, Linux
  • 메모리: 최소 512MB RAM
  • 디스크 공간: 100MB 이상

🔧 설치 및 실행

1단계: 저장소 클론

git clone <repository-url>
cd argu-x-server

2단계: 의존성 설치

# Go 모듈 초기화 및 의존성 설치
go mod tidy

# 의존성 다운로드
go mod download

3단계: 환경 설정

# .env 파일 복사 (환경에 따라)
cp .env .env.local

4단계: 서버 실행

개발 모드 실행

# 기본 포트(8000)로 실행
go run main.go

# 또는 특정 포트로 실행
PORT=3000 go run main.go

프로덕션 빌드 및 실행

# 최적화된 빌드
go build -ldflags "-s -w" -o server main.go

# 실행
./server

5단계: 서버 확인

서버가 성공적으로 시작되면 다음과 같은 로그를 확인할 수 있습니다:

🚀 Starting Argu-X Server...
📅 Started at: 2025-01-22 15:04:05
──────────────────────────────────────────────────
🔌 Connecting to database...
✅ Database connected and migrated successfully
🔧 Gin mode set to: release
🚀 Setting up server...
✅ Server setup completed
🌐 Server starting on port 8000
📊 Health check available at: http://localhost:8000/health
🔗 API available at: http://localhost:8000/api/v1
⏱️  Timeouts - Read: 15s, Write: 15s, Idle: 60s
✅ Server started successfully

⚙️ 환경 설정

서버는 환경 변수를 통해 설정됩니다. .env 파일을 수정하여 설정을 변경할 수 있습니다.

환경 변수 설정 파일

.env 파일을 생성하거나 수정하여 다음 변수들을 설정하세요:

# JWT 설정
JWT_SECRET=your-super-secret-jwt-key-here

# 서버 설정
PORT=8000
GIN_MODE=release

# 데이터베이스 설정
DATABASE_URL=argux.db

# CORS 설정
ALLOWED_ORIGINS=*

# 로깅 설정
LOG_LEVEL=info

# 타임아웃 설정 (초)
READ_TIMEOUT=15
WRITE_TIMEOUT=15
IDLE_TIMEOUT=60

환경 변수 상세

변수명 설명 기본값 필수 예시
JWT_SECRET JWT 서명용 비밀 키 "argu-x" 강력한 32자 이상 문자열
PORT 서버 포트 8000 3000, 8080, 9000
GIN_MODE Gin 모드 release debug, release, test
DATABASE_URL SQLite 파일 경로 "argux.db" ./data/app.db
ALLOWED_ORIGINS CORS 허용 도메인 "*" https://example.com
LOG_LEVEL 로그 레벨 info debug, info, warn, error
READ_TIMEOUT HTTP 읽기 타임아웃 15 30, 60
WRITE_TIMEOUT HTTP 쓰기 타임아웃 15 30, 60
IDLE_TIMEOUT HTTP 유휴 타임아웃 60 120, 300

🌐 API 엔드포인트

Base URL

http://localhost:8000

📊 헬스체크

서버 상태를 확인하는 간단한 엔드포인트

  • GET /health
  • 응답: {"status": "ok"}

🔐 인증 API

회원가입

새로운 사용자 계정을 생성합니다.

  • POST /api/v1/signup
  • Content-Type: application/json

요청 본문:

{
  "name": "사용자명",
  "email": "user@example.com",
  "password": "비밀번호"
}

응답:

{
  "message": "User created successfully",
  "user": {
    "id": 1,
    "name": "사용자명",
    "email": "user@example.com",
    "created_at": "2025-01-22T15:04:05Z"
  }
}

로그인

JWT 토큰을 받아서 인증합니다.

  • POST /api/v1/login
  • Content-Type: application/json

요청 본문:

{
  "email": "user@example.com",
  "password": "비밀번호"
}

응답:

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": {
    "id": 1,
    "name": "사용자명",
    "email": "user@example.com",
    "argx": 10
  }
}

🔒 보호된 API (JWT 필요)

사용자 프로필 조회

현재 로그인된 사용자의 프로필 정보를 반환합니다.

  • GET /api/v1/profile
  • Authorization: Bearer <JWT_TOKEN>

모든 사용자 목록 조회

시스템의 모든 사용자 정보를 반환합니다.

  • GET /api/v1/users
  • Authorization: Bearer <JWT_TOKEN>

특정 사용자 조회

ID로 특정 사용자 정보를 조회합니다.

  • GET /api/v1/users/:id
  • Authorization: Bearer <JWT_TOKEN>

응답 예시:

[
  {
    "id": 1,
    "name": "사용자명",
    "email": "user@example.com",
    "avatar": "",
    "argx": 10,
    "created_at": "2025-01-22T15:04:05Z",
    "updated_at": "2025-01-22T15:04:05Z"
  }
]

💬 토론 API

토론 생성

새로운 토론을 생성합니다.

  • POST /api/v1/debates
  • Authorization: Bearer <JWT_TOKEN>
  • Content-Type: application/json

요청 본문:

{
  "title": "토론 제목",
  "description": "토론 설명",
  "category": "기술",
  "image": "https://example.com/image.jpg",
  "cons_title": "반대 측 제목",
  "pros_title": "찬성 측 제목",
  "start_at": "2025-01-22",
  "end_at": "2025-01-23"
}

토론 목록 조회

모든 토론을 조회합니다.

  • GET /api/v1/debates

특정 토론 조회

ID로 특정 토론을 조회합니다.

  • GET /api/v1/debates/:id
  • Authorization: Bearer <JWT_TOKEN>

인사이트 생성

토론의 특정 측면에 인사이트를 추가합니다.

  • POST /api/v1/debates/:id/insights
  • Authorization: Bearer <JWT_TOKEN>
  • Content-Type: application/json

요청 본문:

{
  "content": "인사이트 내용",
  "debate_side_id": 1,
  "argx": 10
}

인사이트 투표

인사이트에 ARGX 토큰으로 투표합니다.

  • POST /api/v1/debates/:id/insights/:insight_id/vote
  • Authorization: Bearer <JWT_TOKEN>
  • Content-Type: application/json

요청 본문:

{
  "insight_id": 1,
  "argx": 5
}

댓글 작성

토론에 댓글을 작성합니다.

  • POST /api/v1/debates/:id/comments
  • Authorization: Bearer <JWT_TOKEN>
  • Content-Type: application/json

요청 본문:

{
  "content": "댓글 내용",
  "debate_id": 1
}

🌐 실시간 WebSocket API

토론 실시간 구독

WebSocket을 통해 특정 토론의 실시간 업데이트를 구독합니다.

  • WebSocket ws://localhost:8000/api/v1/ws/debates/:id

기능:

  • 토론 정보 실시간 업데이트
  • 인사이트 추가/수정 시 전체 토론 정보 전송
  • 투표 및 댓글 작성 시 실시간 반영

사용 예시:

const ws = new WebSocket('ws://localhost:8000/api/v1/ws/debates/1');

ws.onmessage = (event) => {
  const debateData = JSON.parse(event.data);
  console.log('Debate updated:', debateData);
};

📁 프로젝트 구조

argu-x-server/
├── src/                          # 소스 코드
│   ├── core/                     # 핵심 모듈
│   │   ├── config/              # 설정 관련
│   │   │   ├── database.go      # 데이터베이스 연결 설정
│   │   │   └── jwt.go           # JWT 토큰 설정
│   │   ├── middleware/          # 미들웨어
│   │   │   └── auth.go          # JWT 인증 미들웨어
│   │   └── websocket/           # WebSocket 관리
│   │       └── manager.go       # WebSocket 연결 및 브로드캐스트 관리
│   └── v1/                      # API 버전 1
│       ├── routes/              # 라우팅
│       │   └── router.go        # 라우트 정의
│       ├── debate/              # 토론 모듈
│       │   ├── controller.go    # HTTP 핸들러
│       │   ├── service.go       # 비즈니스 로직
│       │   ├── repository.go    # 데이터 액세스
│       │   ├── model.go         # 데이터 모델
│       │   └── dto.go           # 데이터 전송 객체
│       └── user/                # 사용자 모듈
│           ├── controller.go    # HTTP 핸들러
│           ├── service.go       # 비즈니스 로직
│           ├── repository.go    # 데이터 액세스
│           ├── model.go         # 데이터 모델
│           └── dto.go           # 데이터 전송 객체
├── WEBSOCKET_README.md          # WebSocket 기능 문서
├── .env                         # 환경 변수 (예시)
├── .env.local                   # 로컬 환경 변수
├── .gitignore                   # Git 제외 파일
├── go.mod                       # Go 모듈 정의
├── go.sum                       # 의존성 체크섬
├── main.go                      # 애플리케이션 진입점
└── README.md                    # 프로젝트 문서

아키텍처 설명

🎯 Clean Architecture

프로젝트는 Clean Architecture 원칙을 따르며, 다음과 같은 계층으로 구성됩니다:

  1. Handler/Controller: HTTP 요청/응답 처리
  2. Service: 비즈니스 로직 처리
  3. Repository: 데이터 액세스 추상화
  4. Model: 데이터 구조 정의

📦 모듈별 설명

  • Core Module: 애플리케이션의 핵심 기능을 담당

    • config: 데이터베이스, JWT 등 설정
    • middleware: HTTP 미들웨어 (인증 등)
    • websocket: WebSocket 연결 관리 및 실시간 브로드캐스트
  • V1 Module: API 버전 1의 모든 기능

    • routes: URL 라우팅 정의
    • user: 사용자 관리 모듈
    • debate: 토론 플랫폼 모듈 (ARGX 토큰 시스템 포함)

🛠️ 개발 가이드

개발 환경 설정

1. Go 개발 환경

# Go 버전 확인
go version

# 개발 도구 설치
go install github.com/cosmtrek/air@latest  # 핫 리로딩

2. 디버그 모드 실행

# 환경 변수 설정
export GIN_MODE=debug
export PORT=3000

# 서버 실행
go run main.go

3. 핫 리로딩 설정

air을 사용하여 코드 변경 시 자동으로 서버 재시작:

# air 설정 파일 생성 (.air.toml)
air init

# air로 개발 서버 실행
air

코드 작성 가이드

1. 네이밍 컨벤션

  • 파일명: 소문자, 언더스코어 사용 (e.g., user_controller.go)
  • 함수명: 카멜케이스 (e.g., GetUserByID)
  • 변수명: 카멜케이스 (e.g., userName)
  • 상수: 대문자, 언더스코어 (e.g., MAX_RETRY_COUNT)

2. 에러 처리

// 좋은 예시
if err != nil {
    log.Printf("❌ Error occurred: %v", err)
    c.JSON(http.StatusInternalServerError, gin.H{"error": "Internal server error"})
    return
}

3. 데이터베이스 모델

// GORM 태그를 활용한 모델 정의
type User struct {
    gorm.Model
    Name     string `json:"name" gorm:"type:varchar(100)"`
    Email    string `json:"email" gorm:"uniqueIndex;type:varchar(150);not null"`
    Password string `json:"-" gorm:"type:varchar(255);not null"`
}

데이터베이스 마이그레이션

GORM의 AutoMigrate 기능을 사용하여 스키마가 자동으로 생성됩니다:

// main.go에서 자동 마이그레이션
if err := config.DB.AutoMigrate(&user.User{}); err != nil {
    log.Fatal("❌ Failed to migrate database:", err)
}

🚀 배포

프로덕션 빌드

# 최적화된 바이너리 생성
go build -ldflags "-s -w" -o server main.go

# 실행 파일 권한 설정 (Linux/macOS)
chmod +x server

Docker 배포

# Dockerfile
FROM golang:1.25-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -ldflags "-s -w" -o server main.go

FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/server .
COPY --from=builder /app/.env .
CMD ["./server"]

환경 변수 설정 (배포용)

# 프로덕션 환경 변수
export GIN_MODE=release
export PORT=8000
export JWT_SECRET=your-production-secret-key
export DATABASE_URL=/data/argux.db

🔍 로깅 시스템

서버는 이모지와 함께 구조화된 로깅을 제공합니다:

이모지 설명 사용처
🚀 서버 시작/설정 서버 부팅, 설정 로드
🔌 데이터베이스 DB 연결, 마이그레이션
🌐 네트워크/HTTP HTTP 요청, 응답
성공 정상적인 작업 완료
오류 에러 발생
⚠️ 경고 주의사항
🛑 종료 서버 종료

로그 레벨

  • Debug: 상세한 디버깅 정보
  • Info: 일반적인 정보 메시지
  • Warn: 경고 메시지
  • Error: 오류 메시지

🛡️ 보안 고려사항

1. JWT 보안

  • 강력한 비밀 키 사용 (32자 이상)
  • 토큰 만료 시간 설정
  • HTTPS 환경에서만 사용

2. 비밀번호 보안

  • bcrypt 해싱 사용
  • 최소 8자 이상 복잡한 비밀번호 정책

3. CORS 설정

  • 프로덕션에서는 AllowOrigins를 특정 도메인으로 제한
  • AllowCredentials: true 설정 시 보안 주의

4. 환경 변수

  • .env 파일을 Git에서 제외 (.gitignore)
  • 프로덕션에서는 시스템 환경 변수 사용

🧪 테스트

단위 테스트 실행

# 모든 테스트 실행
go test ./...

# 특정 패키지 테스트
go test ./src/v1/user/...

# 벤치마크 실행
go test -bench=. ./...

테스트 작성 예시

func TestUserService(t *testing.T) {
    // 테스트 코드
}

📊 모니터링

헬스체크

# 서버 상태 확인
curl http://localhost:8000/health

# 응답: {"status": "ok"}

로그 모니터링

# 서버 로그 실시간 확인
tail -f logs/server.log

# 또는 Docker 로그
docker logs -f container_name

🐛 문제 해결

자주 발생하는 문제들

1. 포트 충돌

# 포트 사용 중인 프로세스 확인
lsof -i :8000

# 다른 포트 사용
PORT=3001 go run main.go

2. 데이터베이스 연결 오류

# 데이터베이스 파일 권한 확인
ls -la argux.db

# 권한 수정
chmod 666 argux.db

3. 의존성 문제

# 모듈 정리
go mod tidy

# 캐시 정리
go clean -modcache

4. CORS 오류

  • 브라우저 개발자 도구에서 확인
  • ALLOWED_ORIGINS 환경 변수 설정
  • 프론트엔드 URL을 허용 도메인에 추가

디버깅 모드 활성화

export GIN_MODE=debug
export LOG_LEVEL=debug
go run main.go

🤝 기여

프로젝트 발전에 기여하고 싶으시다면:

  1. Fork 저장소
  2. Feature 브랜치 생성 (git checkout -b feature/amazing-feature)
  3. 변경사항 적용
  4. 테스트 추가
  5. Pull Request 제출

기여 가이드라인

  • 코드 리뷰를 위해 작은 단위로 변경
  • 테스트 코드와 함께 제출
  • 문서 업데이트
  • 기존 코드 스타일 준수

📝 라이선스

이 프로젝트는 MIT 라이선스 하에 제공됩니다. 자세한 내용은 LICENSE 파일을 참조하세요.


📞 지원

문의사항이나 버그 리포트는 다음 채널을 이용해주세요:

🐳 Docker 배포

GitHub Actions를 사용하여 자동으로 Docker 이미지를 빌드하고 GitHub Container Registry(GHCR)에 푸시하는 방법입니다.

사전 요구사항

  1. GitHub 저장소 설정에서 Settings > Secrets and variables > Actions로 이동
  2. New repository secret을 클릭하여 다음 시크릿을 추가:
    • DOCKERHUB_USERNAME: Docker Hub 사용자명 (Docker Hub 사용 시)
    • DOCKERHUB_TOKEN: Docker Hub 액세스 토큰 (Docker Hub 사용 시)

배포 방법

  1. main 브랜치에 푸시하면 자동으로 GitHub Actions가 실행됩니다.
  2. 성공적으로 빌드되면 GitHub Packages에서 이미지를 확인할 수 있습니다.

로컬에서 실행

# GitHub Container Registry에서 이미지 가져오기
docker pull ghcr.io/username/argu-x-server:main

# 컨테이너 실행
docker run -p 8080:8080 ghcr.io/username/argu-x-server:main

환경 변수 설정

필요한 환경 변수는 .env 파일을 사용하거나 -e 플래그로 전달할 수 있습니다.

docker run -p 8080:8080 --env-file .env ghcr.io/username/argu-x-server:main

🔄 업데이트 로그

v1.1.0 (2025-01-22)

  • ⚡ 실시간 WebSocket 기능 추가
  • 💬 토론 플랫폼 모듈 추가 (찬반 토론, ARGX 토큰 시스템)
  • 🌐 WebSocket을 통한 실시간 토론 업데이트
  • 📝 WebSocket API 문서화 완료

v1.0.0 (2025-01-22)

  • 초기 릴리즈
  • JWT 인증 시스템
  • 사용자 관리 API
  • SQLite 데이터베이스
  • 문서화 완료

만든이: Argu-X Team 버전: 1.1.0 최종 업데이트: 2025년 1월 22일