exchangerate.dev는 Server Component 또는 Route Handler에서 호출하고, 키가 포함된 브라우저 코드에서는 절대 호출하지 마세요. Next.js는 업스트림 요청을 60초마다 재검증할 수 있으며, 응답 필드 source, market_session, data_updated_at은 캐시된 값이 실제로 무엇을 의미하는지 UI에 알려줍니다.
EXCHANGERATE_API_KEY는 서버 전용 환경 변수에 보관하세요. NEXT_PUBLIC_ 접두사를 절대 붙이지 마세요.fetch와 next: { revalidate: 60 }을 사용해 페이지 조회마다 업스트림 요청이 발생하지 않도록 하세요.timestamp를 신선도의 증거로 삼지 말고, data_updated_at을 표시하세요.서버 측에서 가져오기
Server Component는 브라우저 밖에서 실행되므로 비공개 환경 변수를 읽을 수 있습니다. 아래 예제는 USD 대비 EUR과 GBP만 요청하고, HTTP 상태를 확인한 뒤 타입이 지정된 JSON을 페이지로 반환합니다.
type LatestRates = {
base: string;
source: "live" | "ecb_daily" | "market_daily";
market_session: string;
data_updated_at: string;
rates: Record<string, number>;
};
async function getRates(): Promise<LatestRates> {
const apiKey = process.env.EXCHANGERATE_API_KEY;
if (!apiKey) throw new Error("EXCHANGERATE_API_KEY is missing");
const response = await fetch(
"https://api.exchangerate.dev/v1/latest/USD?symbols=EUR,GBP",
{
headers: { Authorization: `Bearer ${apiKey}` },
next: { revalidate: 60 },
},
);
if (!response.ok) {
throw new Error(`FX request failed: ${response.status}`);
}
return response.json() as Promise<LatestRates>;
}
export default async function Page() {
const fx = await getRates();
return (
<main>
<p>1 USD = {fx.rates.EUR} EUR</p>
<small>
{fx.source} · {fx.market_session} · updated {fx.data_updated_at}
</small>
</main>
);
}요청을 캐시하고 관측 시각을 보존하기
next: { revalidate: 60 }은 업스트림 요청의 캐시 수명을 최대 60초로 제한합니다. 이는 페이지 조회마다 중복 호출이 발생하는 것을 줄여주지만, 일별 참조 환율을 장중 실시간 환율로 만들어 주지는 않으므로 값 옆에 source, market_session, data_updated_at을 함께 보관하세요.
NEXT_PUBLIC_ 접두사가 붙은 환경 변수는 브라우저 번들에 포함될 수 있습니다. 이 비밀 값은 EXCHANGERATE_API_KEY로 이름 짓고 서버 코드에서만 읽으세요. 익명 호출은 간단한 테스트에는 괜찮지만, 프로덕션 코드에서는 키를 사용해야 합니다.표시 통화와 정산 통화를 분리하기
스토어프론트는 인디케이티브 환율로 대략적인 현지 가격을 표시할 수 있습니다. 수수료, 스프레드, 반올림, 정산 시점에 따라 체결 금액이 달라질 수 있으므로 최종 청구 금액은 결제 제공업체 또는 거래 체결 기관에서 가져와야 합니다.
- API 키를 서버에 보관하세요.
- 401이나 429 오류가 아니라 성공한 응답만 캐시하세요.
- 신선도가 중요할 때는 환율 출처와 관측 시각을 표시하세요.
- 원래 상품 가격과 통화를 정산의 근거로 유지하세요.
