네이버 블로그, 네이버 뉴스, 구글 검색을 통합하여 제공하는 REST API 서버입니다.
- 네이버 블로그 검색: 네이버 검색 API를 통한 블로그 검색
- 네이버 뉴스 검색: 네이버 검색 API를 통한 뉴스 검색
- 구글 검색: Google Custom Search API를 통한 웹 검색
- 통합 검색: 여러 검색 소스를 한 번에 조회
- API 키 인증: 헤더 기반 인증으로 보안 강화
- CORS 지원: Cross-Origin 요청 지원
- Graceful Shutdown: 안전한 서버 종료
- 언어: Go 1.21+
- 웹 프레임워크: Gin
- 환경변수 관리: godotenv
- HTTP 클라이언트: 표준 net/http
search-api/
├── cmd/api/ # 메인 애플리케이션 진입점
│ └── main.go
├── internal/ # 프라이빗 패키지
│ ├── config/ # 설정 관리
│ ├── model/ # 데이터 모델
│ ├── service/ # 비즈니스 로직
│ ├── handler/ # HTTP 핸들러
│ └── middleware/ # 미들웨어 (CORS, 인증)
├── .env.sample # 환경변수 샘플
├── .gitignore
├── Dockerfile # Docker 빌드 설정
├── docker-compose.yml # Docker Compose 설정
├── go.mod
└── README.md
두 가지 실행 방법을 제공합니다:
- 방법 1: Go로 직접 실행
- 방법 2: Docker/Docker Compose로 실행 (추천)
- Go 1.21 이상
- 네이버 검색 API 키 (네이버 개발자 센터)
- Google Custom Search API 키 (Google Cloud Console)
git clone <repository-url>
cd search-api.env.sample 파일을 .env로 복사하고 API 키를 입력합니다:
cp .env.sample .env.env 파일 내용:
# 서버 설정
SERVER_PORT=8000
SERVER_HOST=0.0.0.0
API_KEY=your_custom_api_key # 원하는 API 키로 변경하세요
# 네이버 검색 API 설정
NAVER_CLIENT_ID=your_naver_client_id
NAVER_CLIENT_SECRET=your_naver_client_secret
# 구글 검색 API 설정
GOOGLE_SEACH_ENGINE_ID=your_google_cse_id
GOOGLE_API_KEY=your_google_api_key중요: API_KEY는 이 API를 호출할 때 사용할 인증 키입니다. 원하는 값으로 변경하세요.
go mod downloadgo run cmd/api/main.go또는 빌드 후 실행:
go build -o search-api cmd/api/main.go
./search-api서버가 성공적으로 시작되면:
=== 통합 검색 API 서버 시작 ===
서버 주소: http://0.0.0.0:8000
서버를 중지하려면 Ctrl+C를 누르세요
- Docker 및 Docker Compose
cp .env.sample .env
# .env 파일을 편집하여 API 키들을 입력하세요# 빌드 및 실행
docker-compose up -d
# 로그 확인
docker-compose logs -f
# 중지
docker-compose down# 이미지 빌드
docker build -t search-api .
# 컨테이너 실행
docker run -d \
--name search-api \
-p 8000:8000 \
--env-file .env \
search-api
# 로그 확인
docker logs -f search-api
# 중지 및 삭제
docker stop search-api
docker rm search-api# 헬스 체크
curl http://localhost:8000/health
# 서버 상태
curl http://localhost:8000/GET /
응답 예시:
{
"message": "통합 검색 API 서버가 정상 작동 중입니다",
"version": "1.0.0",
"endpoints": {
"search": "/search (POST) - API 키 필요",
"health": "/health"
}
}GET /health
응답 예시:
{
"status": "healthy",
"message": "서버가 정상 작동 중입니다"
}모든 보호된 엔드포인트는 요청 헤더에 key 값이 필요합니다:
key: abcd123456
POST /search
Content-Type: application/json
key: abcd123456
요청 본문:
{
"query": "AI 기술",
"enable_blog": true,
"enable_news": true,
"enable_google": true,
"results_per_source": 5
}파라미터 설명:
query(필수): 검색할 키워드enable_blog(선택, 기본값: true): 네이버 블로그 검색 활성화enable_news(선택, 기본값: true): 네이버 뉴스 검색 활성화enable_google(선택, 기본값: true): 구글 검색 활성화results_per_source(선택, 기본값: 10): 각 소스별 결과 개수 (1-50)
응답 예시:
{
"query": "AI 기술",
"results": [
{
"title": "인공지능 기술의 최신 동향",
"content": "AI 기술이 빠르게 발전하고 있습니다...",
"url": "https://example.com/blog/ai-trends",
"source": "네이버 블로그"
},
{
"title": "AI 산업 전망",
"content": "2024년 AI 기술 시장은...",
"url": "https://news.example.com/ai-industry",
"source": "네이버 뉴스"
}
],
"summary": {
"total_results": 15,
"sources_used": ["네이버 블로그", "네이버 뉴스", "구글 검색"]
}
}GET /search/:query?enable_blog=true&enable_news=false&results_per_source=3
key: abcd123456
예시:
curl -H "key: abcd123456" "http://localhost:8000/search/파이썬?results_per_source=3"GET /api-status
key: abcd123456
응답 예시:
{
"naver_api": {
"client_id_configured": true,
"client_secret_configured": true
},
"google_api": {
"api_key_configured": true,
"cse_id_configured": true
},
"authentication": {
"status": "인증됨",
"message": "올바른 API 키로 인증되었습니다"
}
}# POST 방식 통합 검색
curl -X POST http://localhost:8000/search \
-H "Content-Type: application/json" \
-H "key: abcd123456" \
-d '{
"query": "Go 언어",
"enable_blog": true,
"enable_news": true,
"enable_google": false,
"results_per_source": 5
}'
# GET 방식 간단 검색
curl -H "key: abcd123456" "http://localhost:8000/search/Go언어?results_per_source=3"const response = await fetch('http://localhost:8000/search', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'key': 'abcd123456'
},
body: JSON.stringify({
query: 'Go 언어',
enable_blog: true,
enable_news: true,
enable_google: true,
results_per_source: 5
})
});
const data = await response.json();
console.log(data);import requests
response = requests.post(
'http://localhost:8000/search',
headers={'key': 'abcd123456'},
json={
'query': 'Go 언어',
'enable_blog': True,
'enable_news': True,
'enable_google': True,
'results_per_source': 5
}
)
print(response.json())API는 오류 발생 시 다음과 같은 형식으로 응답합니다:
{
"error": "Unauthorized",
"message": "API key is required. Please include 'key' header in your request."
}200 OK: 요청 성공400 Bad Request: 잘못된 요청 (검증 실패)401 Unauthorized: 인증 실패 (API 키 없음 또는 잘못됨)500 Internal Server Error: 서버 내부 오류
go test ./...go build -o search-api cmd/api/main.go이 프로젝트는 다음의 Go Best Practices를 적용했습니다:
- Standard Go Project Layout: 표준 프로젝트 구조
- 인터페이스 기반 설계: 테스트 가능한 코드
- 의존성 주입: 느슨한 결합
- Context 사용: 타임아웃 및 취소 지원
- Graceful Shutdown: 안전한 서버 종료
- 구조화된 로깅: 명확한 로그 메시지
- 에러 핸들링: 적절한 에러 처리 및 반환
- Multi-stage Docker Build: 최적화된 이미지 크기
- Health Check: Docker 헬스 체크 지원
MIT License
Issue 및 Pull Request를 환영합니다!