[React] 코딩 타자 연습 사이트 만들기 (12) - 참고 레포지토리 추가

Maple·2024년 10월 28일
0

코드보기 : https://github.com/maplesyrup0423/DevTyper

참고 레포지토리 추가

기존 코드의 경우 다양한 데이터 처리와 유틸리티 기능을 제공하여 배열, 문자열, 객체 작업을 간단하게 해주는 라이브러리인 Lodash의 레포지토리에서만 코드를 조회해서 보여줬다.
코드 다양성을 위해 다음 레포지토리들을 추가했다.

  • lodash/lodash // Lodash 레포지토리
  • axios/axios // Axios 레포지토리
  • facebook/react // React 레포지토리
  • ramda/ramda // Ramda 레포지토리
  • jquery/jquery // jQuery 레포지토리
  • mrdoob/three.js // Three.js 레포지토리
  • d3/d3 // D3.js 레포지토리
  • chartjs/Chart.js // Chart.js 레포지토리
  • expressjs/express // Express 레포지토리
  • angular/angular // Angular 레포지토리
  • vuejs/vue // Vue.js 레포지토리
  • airbnb/lottie-web // Lottie-web 레포지토리
  • vercel/next.js // Next.js 레포지토리
  • socketio/socket.io // Socket.IO 레포지토리

주요 수정 사항

  • 여러 레포지토리 배열: repositories 배열에 여러 GitHub 레포지토리를 저장하고, 반복문을 통해 각각의 레포지토리에 대해 검색 요청을 보냅니다.
  • 에러 처리: 특정 레포지토리의 요청에 실패할 경우, 해당 요청을 건너뛰고 다음 레포지토리로 넘어가도록 에러 처리를 추가했습니다.
  // GitHub API에서 여러 레포지토리의 .js 파일을 가져오는 함수
  const fetchJSFilesFromGithub = async () => {
    const GITHUB_TOKEN = process.env.REACT_APP_GITHUB_TOKEN;
    const repositories = [
      "lodash/lodash", // Lodash 레포지토리
      "axios/axios", // Axios 레포지토리
      "facebook/react", // React 레포지토리
      "ramda/ramda", // Ramda 레포지토리
      "jquery/jquery", // jQuery 레포지토리
      "mrdoob/three.js", // Three.js 레포지토리
      "d3/d3", // D3.js 레포지토리
      "chartjs/Chart.js", // Chart.js 레포지토리
      "expressjs/express", // Express 레포지토리
      "angular/angular", // Angular 레포지토리
      "vuejs/vue", // Vue.js 레포지토리
      "airbnb/lottie-web", // Lottie-web 레포지토리
      "vercel/next.js", // Next.js 레포지토리
      "socketio/socket.io", // Socket.IO 레포지토리
    ];

    const query = "extension:js"; // .js 파일 검색 쿼리

    try {
      for (const repo of repositories) {
        const response = await fetch(
          `https://api.github.com/search/code?q=${query}+repo:${repo}`,
          {
            headers: {
              Authorization: `token ${GITHUB_TOKEN}`, // 토큰을 인증 헤더에 추가
            },
          }
        );

        if (!response.ok) {
          console.log(`${repo}의 GitHub API 요청 실패: ${response.status}`);
          continue; // 현재 요청이 실패하면 다음 레포지토리로 넘어감
        }

        const data = await response.json();
        if (data.items.length > 0) {
          const randomItem =
            data.items[Math.floor(Math.random() * data.items.length)];
          await fetchCodeSnippet(randomItem); // 랜덤 파일의 코드 스니펫 가져오기
        } else {
          console.log(`${repo}에 적합한 파일이 없습니다.`);
        }
      }
    } catch (error) {
      console.error("에러 발생:", error.message);
    }
  };

이슈

위 코드처럼 각 레포지토리를 요청하는 경우
요청이 너무 많아 403에러가 뜨는 이슈가 있음

GET https://api.github.com/search/code?q=extension:js+repo:vercel/next.js 403 (Forbidden)

해결

이를 해결하기 위해 레포지토리 목록에서 랜덤으로 하나를 선택한 후 해당 레포지토리에서 .js 파일을 요청하도록 코드를 수정

 // GitHub API에서 여러 레포지토리의 .js 파일을 가져오는 함수
  const fetchJSFilesFromGithub = async () => {
    const GITHUB_TOKEN = process.env.REACT_APP_GITHUB_TOKEN;
    const repositories = [
      "lodash/lodash", // Lodash 레포지토리
      "axios/axios", // Axios 레포지토리
      "facebook/react", // React 레포지토리
      "ramda/ramda", // Ramda 레포지토리
      "jquery/jquery", // jQuery 레포지토리
      "mrdoob/three.js", // Three.js 레포지토리
      "d3/d3", // D3.js 레포지토리
      "chartjs/Chart.js", // Chart.js 레포지토리
      "expressjs/express", // Express 레포지토리
      "angular/angular", // Angular 레포지토리
      "vuejs/vue", // Vue.js 레포지토리
      "airbnb/lottie-web", // Lottie-web 레포지토리
      "vercel/next.js", // Next.js 레포지토리
      "socketio/socket.io", // Socket.IO 레포지토리
    ];
    const randomRepo =
      repositories[Math.floor(Math.random() * repositories.length)];
    const query = "extension:js"; // .js 파일 검색 쿼리

    try {
      const response = await fetch(
        `https://api.github.com/search/code?q=${query}+repo:${randomRepo}`,
        {
          headers: {
            Authorization: `token ${GITHUB_TOKEN}`, // 토큰을 인증 헤더에 추가
          },
        }
      );
      if (!response.ok) {
        console.log(`${randomRepo}의 GitHub API 요청 실패: ${response.status}`);
        return; // 요청 실패 시 함수 종료
      }

      const data = await response.json();
      if (data.items.length > 0) {
        const randomItem =
          data.items[Math.floor(Math.random() * data.items.length)];
        await fetchCodeSnippet(randomItem); // 랜덤 파일의 코드 스니펫 가져오기
      } else {
        console.log(`${randomRepo}에 적합한 파일이 없습니다.`);
      }
    } catch (error) {
      console.error("에러 발생:", error.message);
    }
  };

레포지토리 목록을 배열로 만들어서 관리가 용이하게 작성함.

0개의 댓글