여행 프로젝트 1탄 - DB 설계, 생성 (erdcloud, supabase)
데브코스에서의 첫 팀 프로젝트로여행 계획 및 추천 플랫폼을 개발하게 되었다. 지금까지 약 3주간의 학습 내용으로는프론트 : React, next.js백엔드 : MySQL, supabase정도였고, 이를 활용하여 아웃풋을
jooky.tistory.com
지난 글에 이은 여행 프로젝트 2탄을 시작해보겠다.
사실 예고했던 기능들의 구현 과정을 먼저 남기려 했지만
Custom Search API를 드디어 활용할 수 있다는,
따끈따끈한 뿌듯함을 참을 수 없었기에 순서에 변동이 생겼다.
구글의 지도 API는 많이들 활용 하는 것 같았지만
검색 API는 그에비해 활용도가 떨어지나...? 싶었다 (자료가 많이 안나와...)

어쨌든 API를 활용한 후기를 남겨보도록 하겠다.
✅ 순서
1. Custom Search API란?
2. 사전 작업
3. 사용 방법
1️⃣ Custom Search API란?
RestFull 요청을 사용하여 웹 검색 또는 이미지 검색 결과를 JSON 형태로 받아볼 수 있는 API
조금만 풀어보자면
네이버나 구글 등 검색포털에 검색하면 나오는 결과물들 (= 웹 페이지들)
을 여러 메타데이터로 감싸 JSON 형태로 받을 수 있는 하나의 경로 인 것이고,
검색 결과를 내맘대로 활용해서 사용할 수 있다
는 장점을 갖고 있다는게 설명을 대체할 수 있을 것 같다.
아래 사진으로 당장 예시를 보면

실시간 검색 결과에 따라 데이터가 완전히 일치하지는 않지만
왼쪽 검색 결과에 대한 모든 데이터를 오른쪽의 JSON 형식으로 받을 수 있는 것이다.
검색 결과들의 제목만 활용하겠다 하면 title만 가져다가 활용하면 되고,
링크들만 있으면 된다 싶으면 link만 가져다 이러쿵저러쿵 하면 된다.
2️⃣ 사전 작업
네이버나 카카오도 같은 맥락의 API를 제공하는 것으로 알고 있고 사용 방법 또한 상당히 유사할 것 같지만
나는 Google의 Custom Search JSON API 만 사용했다!!!
API를 사용하기 위해 필요한 건
API key 발급, 검색 엔진 생성(ID), 검색 사이트 등록
단 3가지이고 하나씩 살펴보겠다.
1. API key 발급
Google 클라우드 플랫폼
로그인 Google 클라우드 플랫폼으로 이동
accounts.google.com
여기 접속해서 프로젝트를 하나 생성하고

API 및 서비스 - 라이브러리

Custom search api 검색

API 사용해보기를 누르면 여기로 이동하고 [키 가져오기] 버튼을 누르면 API key를 발급받을 수 있다.
이 key는 어디다 잘 적어두면 되고, 이후 [API 및 서비스]로 가보면 Custom Search API를 확인할 수 있다!!
2. 검색 엔진 생성 - ID 확인
Programmable Search Engine by Google
Help people find what they need on your website. Add a customizable search box to your web pages and show fast, relevant results powered by Google.
programmablesearchengine.google.com
이제 여기 접속해서 검색 엔진을 추가한다.
이름이랑 설명, 검색결과를 얻을 페이지 뭐 등등 입력하고 생성하면 된다.
수정 가능하니 대충해도 된다

다음은 이렇게 상세 설정 페이지가 나오게 되는데,
위 사진에 보이는 검색엔진 ID가 검색 결과를 받아오는 중요한 주소니까 역시 잘 적어두도록 하자
참고로 공개 URL은 내가 받아올 검색 결과를 미리보기처럼 확인할 수 있는 곳이다.
들어가서 원하는 검색 결과를 마음껏 두드려보자
3. 검색 사이트 등록
마음껏 두드렸는데 검색 결과가 시원치 않았을 수도 있다.
검색 엔진 설정 페이지에서 바로 아래로 조금 내리면

검색할 사이트를 추가할 수가 있다.
처음 검색엔진 생성할 때 넣었던 주소가 들어있을 텐데, 구글.com만 넣으면 별로 영양가가 없는 것 같다.

실제로 저렇게 구글만 넣고 검색을 해보면 이렇게 형편없는 결과만 나오는 것을 확인할 수 있다.
이것조차 구글링 실력이라면 아하?
여기서 구체적인 사이트를 명시해줘야 기능이 맛있어지는데
나는 여행지에 대한 숙소, 맛집, 볼거리 등 여행에 관련된 데이터들을 얻기 위해 아래처럼 설정을 해두었다.

이제 필요에 따라 여러 설정들을 추가로 해주면
준비 끝이다!!!
3️⃣ 사용 방법
이제 프로젝트에 어떻게 적용시키는지 살펴보자
아 그전에 내 프로젝트에서 DB는 supabase의 도움을 받았고, 프레임워크는 Next.js를 사용했다.
1. 키 등록
키는 당연히 노출되면 안되기 때문에 깃에 올라가지 않는 파일에 저장해야 하고
.env.local 에 저장을 해뒀다.
GOOGLE_API_KEY="사전작업 1번에서 잘 적어둔 API"
GOOGLE_CSE_ID="사전작업 2번에서 잘 적어둔 주소"
변수명은 크게 상관이 없는데
처음에 멋모르고 NEXT_PUBLIC_GOOGLE_API_KEY 이런식으로 지었었다.
.env.local에 적어둔 의미가 사라져버리는, 내 키를 아주 마음껏 공개하기로 작정을 해버린 것이었다.. 강사님 피드백 정말 감사합니다
어차피 클라이언트 측에서 직접 접근 할 필요가 없으니까 NEXT_PUBLIC_ 은 적지 않는걸로 하자.
2. 이제 불러오기만 하면 끝!!!!!!
인데 기본적인 API 요청 URL 형식을 당연히 갖춰야 한다.
const url = `https://www.googleapis.com/customsearch/v1?key=${사전작업1에서 잘 적어둔 API 키}&cx=${사전작업2에서 잘 적어둔 검색엔진 ID}&q=${검색하고싶은 값}`;
앞서 말했듯이 JSON으로 데이터가 날라오기 때문에 받을때 역시 형식을 잘 갖춰서 받기만 하면 된다
const response = await axios.get(url);
또는
const response = await fetch(url);
const data = await response.json();
적합한 HTTP 클라이언트가 뭔지 판단하고, axios나 fetch 중 적절히 사용하면 되겠다.
나같은 경우 axios를 사용했고, 위 response를 콘솔에 찍은 결과가 바로 아래 JSON이다.
{
kind: 'customsearch#search',
url: {
type: 'application/json',
template: 'https://www.googleapis.com/customsearch/v1?q={searchTerms}&num={count?}&start={startIndex?}&lr={language?}&safe={safe?}&cx={cx?}&sort={sort?}&filter={filter?}&gl={gl?}&cr={cr?}&googlehost={googleHost?}&c2coff={disableCnTwTranslation?}&hq={hq?}&hl={hl?}&siteSearch={siteSearch?}&siteSearchFilter={siteSearchFilter?}&exactTerms={exactTerms?}&excludeTerms={excludeTerms?}&linkSite={linkSite?}&orTerms={orTerms?}&dateRestrict={dateRestrict?}&lowRange={lowRange?}&highRange={highRange?}&searchType={searchType}&fileType={fileType?}&rights={rights?}&imgSize={imgSize?}&imgType={imgType?}&imgColorType={imgColorType?}&imgDominantColor={imgDominantColor?}&alt=json'
},
queries: { request: [ [Object] ], nextPage: [ [Object] ] },
context: { title: 'trip-search' },
searchInformation: {
searchTime: 0.429,
formattedSearchTime: '0.43',
totalResults: '29300',
formattedTotalResults: '29,300'
},
items: [
{
kind: 'customsearch#result',
title: '파리 맛집/음식점 추천 순위 Best 10 - Tripadvisor',
htmlTitle: '<b>파리 맛집</b>/음식점 추천 순위 Best 10 - Tripadvisor',
link: 'https://www.tripadvisor.co.kr/Restaurants-g187147-Paris_Ile_de_France.html',
displayLink: 'www.tripadvisor.co.kr',
snippet: '파리 음식점 · 1. New Jawad Longchamp. 4.8 · 2. Chez Cleopatre (Tacoos -Burger) · 3. Assanabel Saint-Germain · 4. Pizzeria Arrivederci · 5. Les Cèdres Du Liban ...',
htmlSnippet: '<b>파리</b> 음식점 · 1. New Jawad Longchamp. 4.8 · 2. Chez Cleopatre (Tacoos -Burger) · 3. Assanabel Saint-Germain · 4. Pizzeria Arrivederci · 5. Les Cèdres Du Liban ...',
formattedUrl: 'https://www.tripadvisor.co.kr/Restaurants-g187147-Paris_Ile_de_France.html',
htmlFormattedUrl: 'https://www.tripadvisor.co.kr/Restaurants-g187147-Paris_Ile_de_France.html',
pagemap: [Object]
}
...
여기서 나는 [title, link, snippet, pagemap의 image] 등을 사용했고

이런식으로 결과 JSON 데이터를 활용했다.
추가로 Custom Search API는 일단위인지 주단위인지 100회 요청하면 끝이다.
개발할때 신나서 요청을 마구잡이로 갈겼더니 하루만에 100회를 채워 요청이 막히는 불상사 발생....
결국 무료 300달러 체험 어쩌구 하는걸로 목숨을 연명할 수 있었다.
사실 구글 공식 문서에 API 사용법이 꽤나 친절하게 잘 나와있었지만 아무래도 실제 사용기를 찾게 되었고,
실제 적용한 사례가 많지도 않은 것 같아 누구 한명에라도 도움이 되었으면 하는 마음에 글을 남긴다.
여행 프로젝트 시리즈로 글을 올리고 있고, 이제 2탄일 뿐인데.......
사실 프로젝트는 진작에 끝나버렸다ㅋㅋㅋㅋㅋ
이번 시리즈는 3탄에서 종결하기로 하고 어떤 내용을 중점적으로 다룰지는 조금만 더 고민 해봐야겠다.
진짜 끝!
'Projects > 여행 계획 및 추천 플랫폼' 카테고리의 다른 글
| 여행 프로젝트 1탄 - DB 설계, 생성 (erdcloud, supabase) (2) | 2025.07.17 |
|---|