[토이프로젝트] 랜덤 아티클 추천 서비스 06 링크에서 Open Graph 메타데이터 긁어오기

대만이·2023년 6월 9일
1
post-thumbnail

링크에서 메타데이터 긁어오기


⚒️ 기존 기능과 변경 사항

기존 토이프로젝트에서는 사용자가 수동으로 제목과 링크를 입력하고 그 값을 db로 넘겨주는 방식이었다. 하지만 노션 등 많은 서비스의 에디터에서 링크를 입력하면 자동으로 미리보기 양식이 나오고 그 안에 제목, description, 썸네일 이미지 등이 배치된다. 여기서 착안하여 랜덤아티클에서도 사용자가 링크만 입력하면 링크가 원래 가지고 있는 메타데이터에서 정보를 가져올 수 있도록 개선하려고 한다.

📚 관련 지식

메타데이터
웹페이지를 구성하는 구조화된 정보를 뜻한다. 제목, 설명, 이미지를 비롯한 수많은 정보를 미리 웹페이지에 입력해놓음으로써 페이지의 정보를 검색엔진에게 빠르게 알려줄 수 있다. HTML의 <Head> 안에 명시된다.

Open Graph
메타데이터를 표기하는 대표적인 방식으로 페이스북에서 개발했다. 다양한 메타데이터를 쉽게, 그리고 통일해서 표시할 수 있도록 정의한 프로토콜이다. og:title, og:type, og:imgae 와 같이 표시된다.

👍 참고 링크의 미리보기 제목, 설명, 이미지를 결정하는 open graph 태그

🏃‍♀️ 개발 과정

openGraphScraper

입력된 URL의 메타데이터를 JSON형식으로 불러오는 라이브러리. OG데이터를 불러오는 가장 대표적인 라이브러리인 openGraphScraper를 사용했다. 웹링크 미리보기나 임베드 카드 등을 만들 때 유용하게 쓰일 것 같다. Readme대로 잘 읽고 따라하니 쉽게 결과가 나오는 줄 알았지만..

CORS에러


역시 한번에 되는건 하나도 없었다. VS Code 콘솔에서 node .. 로 띄웠을 때는 결과값이 잘 나왔는데 브라우저의 콘솔로 옮겨오니 난리가 부르스다.. 이게 무슨말이냐 하면..

CORSCross Origin Resourcing Site
웹주소의 출발지가 되는 origin정보가 다른 사이트끼리 API 요청을 의미한다. SOPSameOriginPolicy 정책에 의하면 origin에 같은 사이트내에서만 api 요청이 가능한데 이는 브라우저 쿠키를 악용한 보완 관련 이슈를 막기 위해서이다.

CORS가 막혀있어도 사용할 수 있다?
사용자가 API 서버에 접속하면 front는 먼저 preflight, 일종의 미리 요청을 보낸다. API 서버는 지금 보내는 요청이 유효한지 확인후 가능여부 값을 응답으로 보내는데 불가능값을 받으면 브라우저측에서 차단한다. 그래서 VS콘솔에서는 보이고 브라우저 콘솔에는 안보였군..!
해결책으로 API에서 값을 받아와서 우리 브라우저에는 yes값을 보내주는 대리서버proxy server를 만들고 우회 요청을 하면 CORS가 막혀있는 API도 받아올 수 있다!고 인프런 프론트엔드 강의에서 들었던 부분이 떠올랐다!

Next.js API routes로 우회서버 만들기

Next.js API routes
Nex.js에서 API서버를 바로 추가할 수 있는 기능을 말한다. pages/api 디렉토리 안에 파일을 만들면 rest api의 경로가 된다.

ChatGPT와의 긴 대화 끝에 천재 프레임워크 Next.js가 api 서버를 만들 수 있다는 사실을 알아냈다. 얼렁뚱땅 API만들기까지 와버리다니.. 역시 프론트 백 나뉘어있어도 양쪽 지식을 다 알아야 하는구나 또 깨닫게 되는 순간..

코드는 다음과 같이 구현했다. chatGPT의 도움을 많이 받았다🥹

📄 pages/api/metadata.js

import ogs from 'open-graph-scraper';

export default async function handler(req, res) {
  const { url } = req.query;

  try {
    const options = { url };
    const data = await ogs(options);
    const { result } = data;

    res.status(200).json({ result });
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: '문제가 발생했습니다.' });
  }
}
📄 list.container.tsx

const [input, setInput] = useState('');
...
const getMetaData = async () => {
    try {
      const response = await fetch(`/api/metadata?url=${input}`);
      const data = await response.json();
      const { result } = data;
      console.log(result);
      return result;
    } catch (error) {
      console.error('getMetaDataError : ', error);
      setOgResult({
        id: '',
        title: '',
        link: '',
        isRead: false,
        description: '',
        image: '',
      });
    }
  };
...
  • pages/api/metadata.js에서 open graph scraper API를 불러오는 우회서버를 만들었다.
  • try{} catch{} 구문으로 에러 처리 허들을 만들었다.
  • getMetaData 함수에서
    • 사용자가 입력한 input변수를 url값으로 요청하고
    • async.. await로 결과값을 가져올 때까지 기다린 후 result로 받아와 사용했다.

🐝 공부해야 할 것들

사실 한번에 API Routes로 해결방법을 찾은것은 아니었다.

  • Next.js의 렌더링 방식을 활용해서 정적 생성 시점에 데이터를 가져오는 방법 시도
    했으나 클라이언트 요청에 따라 동적으로 API 요청을 보내야 하는 나의 상황에 맞지 않아 실패
  • Express 등으로 우회서버를 만들어서 연결 시도
    했으나 찾는 과정에서 Next.js에 이미 서버가 있다!?는 사실을 알아버림

등등 지난한 과정이 있었다. 그 과정에서 깨작거린 getStaticProps, SSR, CSR...에 대해 앞으로 더 공부해야하고, 사실 핵심 방법인 API Route에 대해서도 아직 잘 모르는 것 같아 더 훈련해봐야겠다. 프론트 개발을 위해서는 백엔드 관련 지식도 반드시 알아야 한다는 것도 배웠고..! 일단 원하는 API를 사용하는데 성공했다는 것이 기쁘다. 앞으로 오를 산이 많다. 천천히 꾸준히 올라보자🧗‍♀️

profile
느려도 오래 걷습니다👟

0개의 댓글