본문 바로가기
프로젝트

문제해결_ 공공데이터 일일 트래픽 초과 ( 결국엔 로컬 스토리지1 )

by warrior.p 2024. 3. 12.
  • 지역별 과거 일평균 미세먼치 데이터는 데이터는 하루 한번만 요청하면 되기때문에 이걸 로컬에 저장하고 재사용하도록 했다.(saveDataToLocalStorage) 공공데이터 일일트래픽이 있는데 만들다보니 의도치 않게 초과하여 데이터가 나오지 않는다. useQueries에서는 직접적으로 로컬 스토리지 데이터의 유효성을 검사하고, 이를 기반으로 쿼리 실행 여부를 결정하는 것은 안된다. 대신, 로컬 스토리지에서 데이터를 불러오는 로직을 쿼리 함수 내에서 직접 구현하거나, 쿼리 실행 전에 데이터의 유효성을 검사하여 쿼리 실행 여부를 결정하는 로직을 외부에서 처리해야한다.
  • 로컬 스토리지에 저장된 데이터가 오늘 날짜에 해당하는지 확인하고, 만약 오늘 날짜의 데이터가 없거나 유효하지 않은 경우 API를 호출하여 데이터를 가져오는 오도록 코드를 수정했다.
// 과거미세먼지 데이터 로컬 스토리지에 저장하는 로직(당일)
  const saveToLocalStorage = (msrstnName, data) => {
    try {
      // yyyy-mm-dd
      const today = new Date().toISOString().slice(0, 10);
      const dataWithDate = { data, date: today };
      localStorage.setItem(
        `pastDustData_${msrstnName}`,
        JSON.stringify(dataWithDate)
      );
    } catch (error) {
      console.error('로컬 스토리지 저장 실패', error);
    }
  };
// 데이터 로드시 오늘 날짜랑 로컬스토리지 날짜랑 일치하는지 유효성 확인
  const loadDataWithDailyCheck = msrstnName => {
    const itemStr = localStorage.getItem(`pastDustData_${msrstnName}`);
    if (!itemStr) return { data: null, isValid: false };

    const { data, date } = JSON.parse(itemStr);
    const today = new Date().toISOString().slice(0, 10);
    return { data, isValid: date === today };
  };

  const fetchDataQueries = Object.entries(locationAtoms).map(([msrstnName]) => {
    return {
      queryKey: ['pastDustData', msrstnName],
      queryFn: async () => {
        // 로컬 스토리지에서 데이터 검증
        const { data, isValid } = loadDataWithDailyCheck(msrstnName);
        if (isValid) {
          return data; // 유효한 데이터가 있다면, API 호출 없이 해당 데이터 반환
        } else {
          // API 호출하여 새로운 데이터 가져오기
          const newData = await fetchPastDustData(
            getSixDaysBeforeDate(new Date()),
            getYesterdaysStringDate(new Date()),
            msrstnName
          );
          saveToLocalStorage(msrstnName, newData); // 새로운 데이터를 로컬 스토리지에 저장
          return newData;
        }
      },
      onSuccess: data => {
        //  데이터 fetch 성공 시, Recoil Atom 업데이트
        if (data && data.length > 0) {
          const pastDustHistory = filterLocationInfo(data);
          console.log(pastDustHistory);
          // 각각의 recoil atom 업데이트
          switch (msrstnName) {
            case '고성(DMZ)':
              setGoseongPastState(pastDustHistory);
              break;
            case '양양읍':
              setYangyangPastState(pastDustHistory);
              break;
            case '평창읍':
              setPyeongchangPastState(pastDustHistory);
              break;
            case '주문진읍':
              setGangneungPastState(pastDustHistory);
              break;
            case '금호동':
              setSokchoPastState(pastDustHistory);
              break;
            default:
              break;
          }
        }
      },
    };
  });

useQueries(fetchDataQueries);
  • 실시간 미세먼지가 좋은 지역과 해당지역 미세먼지 수치는 전역적으로 사용하기위해 리코일로 저장.
  • 과거의 지역별 민세먼지 일평균 데이터는 프로젝트 디벨롭을 할 때 필요할수 있으니 리코일 저장, 그리고 로컬에도 저장 (saveToLocalStorage.setItem())