해커톤: 아이디어 도출, 팀 구축, 구현, 입상 전략까지 - Chapter 10 프로젝트
Chapter 10에서는 개인의 목표 관리를 위한 API 서비스를 구축합니다. 이 프로젝트를 통해 Azure Functions 기반의 서버리스 아키텍처, 데이터베이스 모델링, 그리고 체계적인 API 설계 방법을 학습할 수 있습니다.
해커톤의 핵심인 "단기간에 의미있는 결과물 만들기"를 실현하기 위해, 복잡한 인증 시스템 대신 목표 설정과 평가라는 핵심 기능에 집중한 프로젝트입니다.
- 목표 설정: 주별 목표를 설정하고 관리
- 목표 조회: 이번 주/지난 주 목표 조회 및 필터링
- 목표 평가: 완료된 목표에 대한 평가 작성
- 통계 기능: 월별 목표 달성 현황 조회
Chapter 10을 통해 다음을 배울 수 있습니다:
- 서버리스 아키텍처: Azure Functions 기반의 효율적인 API 구축
- 데이터 모델링: 사용자-목표-평가 간의 관계 설계
- API 설계: RESTful API 원칙에 따른 엔드포인트 구성
- 상태 관리: 목표의 생명주기와 상태 변화 관리
- Azure Functions v4: 서버리스 컴퓨팅 플랫폼
- Python 3.9+: 주 개발 언어
- SQLAlchemy 2.0.27: ORM 라이브러리
- MySQL 8.3: 관계형 데이터베이스
- Azure Database for MySQL: 클라우드 데이터베이스 서비스
- OpenAPI 3.0: API 스펙 문서화
-- 사용자 테이블
CREATE TABLE users (
id INT(11) NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
PRIMARY KEY (id)
);
-- 목표 테이블
CREATE TABLE goals (
id INT(11) NOT NULL AUTO_INCREMENT,
user_id INT(11) NOT NULL,
description VARCHAR(255) NOT NULL,
resolved TINYINT(1) NOT NULL DEFAULT 0,
year INT(11) NOT NULL,
month INT(11) NOT NULL,
week INT(11) NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
PRIMARY KEY (id)
);
-- 평가 테이블
CREATE TABLE assessments (
id INT(11) NOT NULL AUTO_INCREMENT,
user_id INT(11) NOT NULL,
year INT(11) NOT NULL,
month INT(11) NOT NULL,
week INT(11) NOT NULL,
content TEXT NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
PRIMARY KEY (id)
);- 사용자의 주별 목표를 관리
- 연도, 월, 주 단위로 구분
- 완료 여부 추적
- 목표에 대한 사용자 평가
- 주별로 하나의 평가만 작성 가능
- 완료된 목표 ID 목록 포함
- 기본 사용자 정보 관리
- 현재는 목업 사용자 ID 사용
POST /goals: 새로운 목표 추가GET /goals: 목표 조회 (주별 필터링 지원)GET /goals/stats: 월별 목표 달성 통계
POST /assessments: 목표 평가 작성GET /assessment: 특정 주의 평가 조회
자세한 API 스펙은 openapi.yaml 파일을 참조하세요.
- Python 3.9 이상
- Azure Functions Core Tools
- Docker (MySQL 실행용)
- Azure CLI (배포용)
# 가상환경 생성 및 활성화
python -m venv venv
source venv/bin/activate # Linux/Mac
# 또는
venv\Scripts\activate # Windows
# 의존성 설치
pip install -r requirements.txt# npm을 통한 설치
npm install -g azure-functions-core-tools@4 --unsafe-perm true
# 또는 Homebrew (Mac)
brew tap azure/functions
brew install azure-functions-core-tools@4Docker를 사용하여 MySQL을 실행합니다:
# MySQL 컨테이너 실행
docker run -e MYSQL_ROOT_PASSWORD=password \
-e MYSQL_DATABASE=setweeklygoals \
-p 3306:3306 \
-d mysql:8.3
# 데이터베이스 스키마 생성
mysql -h localhost -u root -ppassword setweeklygoals < schema.sqllocal.settings.json 파일에서 데이터베이스 연결 설정:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "",
"FUNCTIONS_WORKER_RUNTIME": "python",
"MYSQLCONNSTR_DB": "mysql://root:password@localhost:3306/setweeklygoals"
}
}# Functions 호스트 시작
func host start
# 또는 환경 변수 직접 설정
MYSQLCONNSTR_DB=mysql://root:password@localhost:3306/setweeklygoals func host start성공적으로 실행되면 다음과 같은 메시지가 출력됩니다:
Functions:
add_goal: [POST] http://localhost:7071/api/goals
get_goals: [GET] http://localhost:7071/api/goals
get_goals_stats: [GET] http://localhost:7071/api/goals/stats
add_assessment: [POST] http://localhost:7071/api/assessments
get_assessment: [GET] http://localhost:7071/api/assessment
curl -X POST http://localhost:7071/api/goals \
-H "Content-Type: application/json" \
-d '{"description": "책 한 권 읽기"}'# 이번 주 목표 조회
curl http://localhost:7071/api/goals
# 지난 주 목표 조회
curl http://localhost:7071/api/goals?weekly_offset=1curl -X POST http://localhost:7071/api/assessments \
-H "Content-Type: application/json" \
-d '{
"content": "목표를 설정한 덕에 보람찬 한 주를 보낼 수 있었다",
"year": 2024,
"month": 1,
"week": 1,
"resolvedGoalIds": [1, 2]
}'# Azure CLI 로그인
az login
# 배포 스크립트 실행
let "randomIdentifier=$RANDOM*$RANDOM%10000000000"
location="koreacentral"
resourceGroup="set-weekly-goals-$randomIdentifier"
storage="setweeklygoals$randomIdentifier"
functionApp="set-weekly-goals-app-$randomIdentifier"
dbName="weekly_goals"
dbAdminUser=setweeklygoals
dbAdminPassword=setweeklygoals1!
skuStorage="Standard_LRS"
skuMySQL="Standard_B1s"
functionsVersion="4"
# 리소스 그룹 생성
echo "리소스 그룹 $resourceGroup 을 $location 리전에 생성합니다"
az group create --name "$resourceGroup" --location "$location"
# 스토리지 계정 생성
echo "리소스 그룹 $resourceGroup 에 스토리지 계정을 생성합니다."
az storage account create --name $storage --location "$location" --resource-group $resourceGroup --sku $skuStorage
# 함수 앱 생성
echo "$functionApp 서버리스 함수 앱을 생성합니다"
az functionapp create --name $functionApp --resource-group $resourceGroup --storage-account $storage --consumption-plan-location $location --functions-version $functionsVersion --runtime python --os-type Linux
# MySQL 서버 생성
echo "MySQL 서버 $storage 를 생성합니다."
az mysql flexible-server create --public-access 0.0.0.0 --resource-group $resourceGroup --name $storage --admin-user $dbAdminUser --admin-password $dbAdminPassword --location "$location" --sku-name $skuMySQL
# 데이터베이스 생성
echo "MySQL 서버 $storage 에 데이터베이스 $dbName 을 생성합니다."
az mysql flexible-server db create --resource-group $resourceGroup --database-name $dbName --server-name $storage
# SSL 설정 비활성화
az mysql flexible-server parameter set --name require_secure_transport --value OFF --server-name $storage --resource-group $resourceGroup
# 연결 문자열 구성
mysqlHostName=$(az mysql flexible-server show --resource-group $resourceGroup --name $storage --query "fullyQualifiedDomainName" -o tsv)
mysqlConnectionString="mysql+pymysql://${dbAdminUser}:${dbAdminPassword}@${mysqlHostName}/${dbName}"
echo $mysqlConnectionString
# 함수 앱에 연결 문자열 설정
az webapp config connection-string set --resource-group $resourceGroup --name $functionApp -t mysql --settings "DB=$mysqlConnectionString"# Azure Function 배포
func azure functionapp publish $functionApp# 모든 리소스 삭제
az group delete --name $resourceGroup --yes --no-waitChapter 10에서 다루는 주요 사용자 스토리:
- 목표 설정자로서 이번 주 달성하고 싶은 목표를 설정할 수 있다
- 목표 추적자로서 설정한 목표의 완료 여부를 업데이트할 수 있다
- 자기성찰자로서 지난 주 목표에 대한 평가를 작성할 수 있다
- 진척도 확인자로서 월별 목표 달성 통계를 확인할 수 있다
- 주차별 목표 관리를 위한 시간 기반 데이터 구조 설계
- 목표와 평가 간의 관계 모델링
- RESTful 원칙에 따른 엔드포인트 구성
- 쿼리 매개변수를 활용한 필터링 구현
- 목표의 생명주기 관리 (생성 → 진행 → 완료)
- 평가와 목표 간의 상태 동기화
- Azure Functions의 효율적 활용
- 데이터베이스 연결 풀 관리
- 푸시 알림 기능 (주별 목표 설정/평가 리마인더)
- 목표 카테고리 분류 시스템
- 소셜 기능 (친구와 목표 공유)
- 시각화 대시보드 (차트, 그래프)
- 인증/인가 시스템 도입
- 캐싱 레이어 추가
- 배치 작업을 통한 통계 데이터 생성
- 마이크로서비스 아키텍처로 분리
증상: OperationalError: (2003, "Can't connect to MySQL server")
해결책:
- MySQL 컨테이너가 실행 중인지 확인
- 포트 3306이 사용 가능한지 확인
- 연결 문자열의 호스트/포트/자격증명 검증
증상: Error: subprocess-exited-with-error
해결책:
# Ubuntu
sudo apt install default-libmysqlclient-dev pkg-config -y
# macOS
brew install pkg-config mysql증상: Table 'goals' doesn't exist
해결책:
# 스키마 파일 재실행
mysql -h localhost -u root -ppassword setweeklygoals < schema.sql이 프로젝트는 "해커톤: 아이디어 도출, 팀 구축, 구현, 입상 전략까지" 도서의 Chapter 10 예제입니다. 개선사항이나 질문이 있으시면 Issue를 생성해 주세요.
이 프로젝트는 교육 목적으로 제작되었습니다.