Node.캐시가 js를 통해 API에서 얻은 결과
하고 싶은 일
장면
Next.js의 API를 두드리다.
API를 두들긴 넥스트.js는 RESAS의 API를 호출하여 도도부현의 일람과 도도부현의 전체 인구를 얻었다.
Next.js는 도도부현의 일람표와 총인구의 정보를 API를 두드린 사람에게 되돌려준다.
API를 반복해서 두드리면 Rate Limit에 걸릴 수 있습니다.유료인 API라면 유료다.
도도부현의 정보는 그렇게 빈번하게 변하지 않기 때문에 반복해서 사용해도 문제가 없을 것이다.
Next.js의 서버가 시작된 후, 첫 번째로 RESA의 API를 호출할 것을 요청하였는데, 그 결과는 캐시하고 사용할 수 있습니다.
사용한 라이브러리
node-cache 캐시를 사용하여 결과를 얻습니다.
소스 코드
lib/resas.ts
import axios from 'axios'
import NodeCache from 'node-cache'
const RESAS_API_KEY = process.env.RESAS_API_KEY
const RESAS_ENDPOINT = 'https://opendata.resas-portal.go.jp/api/v1'
type Prefecture = {
prefCode: number
prefName: string
}
type PopulationOfPrefecture = {
prefecture: Prefecture
populations: Population[]
}
type Population = {
year: string
value: string
}
const cache = new NodeCache({ stdTTL: 1000 * 60 * 60 * 24 })
/**
* RESAS API から都道府県リストを取得する。
* @return {Prefecture[]} 都道府県のリスト
* @see [人口構成](https://opendata.resas-portal.go.jp/docs/api/v1/population/composition/perYear.html)
*/
export const getPrefList = async (): Promise<Prefecture[]> => {
if (RESAS_API_KEY == null) throw new Error()
if (cache.get('prefectures')) {
console.log('キャッシュから県の情報を返します。')
return cache.get('prefectures') as Prefecture[]
}
const prefecturesUrl = `${RESAS_ENDPOINT}/prefectures`
const { data } = await axios.get(prefecturesUrl, { headers: { 'X-API-KEY': RESAS_API_KEY } })
const prefectures: Prefecture[] = data.result
cache.set('prefectures', prefectures)
return prefectures
}
/**
* 都道府県コードから都道府県を返す。
* @param {number} prefCode 都道府県コード
* @return {Promise<Prefecture>>} 都道府県
*/
const getPrefById = async (prefCode: number): Promise<Prefecture> => {
const prefectures =
cache.get('prefectures') != null
? (cache.get('prefectures') as Prefecture[])
: await getPrefList()
const pref = prefectures.filter((prefecture) => prefecture.prefCode === prefCode)
if (pref && pref.length !== 0) {
return pref[0]
} else {
throw new Error(`prefCode ${prefCode} doesn't exist.`)
}
}
/**
* prefCode で渡した都道府県の総人口の配列を返す
* @param {number} prefCode RESASの都道府県APIから取得した都道府県ID
* @return {Promise<PopulationOfPrefecture>} 都道府県の総人口推移
*/
export const getAllPopulationByPrefId = async (
prefCode: number
): Promise<PopulationOfPrefecture> => {
if (RESAS_API_KEY == null) throw new Error()
const prefecture = await getPrefById(prefCode)
if (cache.get(`population-prefId-${prefCode}`) != null) {
console.log('キャッシュから総人口の情報を返します。')
const cachedPrefAllPopulations = cache.get(`population-prefId-${prefCode}`) as Population[]
return { prefecture, populations: cachedPrefAllPopulations }
}
const populationByPrefIdUrl = `${RESAS_ENDPOINT}/population/composition/perYear?cityCode=-&prefCode=${prefCode}`
const { data } = await axios.get(populationByPrefIdUrl, {
headers: { 'X-API-KEY': RESAS_API_KEY },
})
const filteredAllPopulations = data.result.data.filter(
(populationData: any) => populationData.label === '総人口'
)
const allPopulations = filteredAllPopulations[0].data
cache.set(`population-prefId-${prefCode}`, allPopulations)
return { prefecture, populations: allPopulations }
}
캐시를 준비하는 부분은 다음과 같습니다.import NodeCache from "node-cache";
const cache = new NodeCache({ stdTTL: 1000 * 60 * 60 * 24 });
캐시가 있는지 확인하는 부분은 다음과 같습니다.if (cache.get(`population-prefId-${prefCode}`) != null) {
console.log('キャッシュから総人口の情報を返します。')
const cachedPrefAllPopulations = cache.get(`population-prefId-${prefCode}`) as Population[]
return { prefecture, populations: cachedPrefAllPopulations }
}
캐시에 저장된 부분은 다음과 같습니다.cache.set(`population-prefId-${prefCode}`, allPopulations);
API
Next.js
pages/api
이하의 API에서 사용한 그림을 호출합니다.await getAllPopulationByPrefId(1)
견본에 고정 파라미터를 전달한다.원래
req
에서 파라미터를 얻어야 하는데, 이 보도의 주제는 아니다.pages/api/populations.ts
import { NextApiRequest, NextApiResponse } from 'next'
import { getAllPopulationByPrefId } from '../../lib/resas'
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const populations = await getAllPopulationByPrefId(1)
res.status(200).json(populations)
}
http://localhost:3000/api/populations
의 응답은 이렇다.{
"prefecture": {
"prefCode": 1,
"prefName": "北海道"
},
"populations": [
{
"year": 1960,
"value": 5039206
},
略
첫 번째 반응이 좀 느렸어요.RESAS에 데이터를 찾으러 가야 하기 때문이다.두 번째부터는 폭발 속도다.
서버 측(Next.js 측)에 두 번째 이후 메시지
キャッシュから総人口の情報を返します。
가 표시됩니다.도도부현 정보를 얻는 API.
pages/api/prefectures.ts
import { NextApiRequest, NextApiResponse } from 'next'
import { getPrefList } from '../../lib/resas'
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const prefectures = await getPrefList()
res.status(200).json(prefectures)
}
http://localhost:3000/api/prefectures
의 응답은 이렇다.[
{
"prefCode": 1,
"prefName": "北海道"
},
{
"prefCode": 2,
"prefName": "青森県"
},
{
"prefCode": 3,
"prefName": "岩手県"
},
略
브라우저도 캐시해야 합니까?
나는 API에서 캐시를 되돌려줌으로써 브라우저 측도 캐시를 할 수 있고 더 빨리 응답할 수 있으며 불필요한 요청을 줄일 수 있다고 생각한다.
브라우저
memory-cache
를 사용하는 것이 좋을 것 같아서 다른 글로 시도해 보세요.How to Cache API Calls in Next.js
Reference
이 문제에 관하여(Node.캐시가 js를 통해 API에서 얻은 결과), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/fjsh/articles/87fffabbe5ebd8텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)