๐ ๊ฒฐ์ ์ฝ๋ฐฑ ํ์ด์ง ์ ์ฉ ์ค serverRuntimeConfig๋ฅผ ๋ค๋ค๋ณด๋ฉฐ..
๊ธฐ์กด์ ํ๋์ ์๋น์ค์์๋ง ์ฌ์ฉํ๋ ๋น๋ง ๋ชจ๋์ ์ธํฐํํฌ์ ๋ ๋ชจ๋์์ ์ฌ์ฉํ ์ ์๋ ํตํฉ ๋น๋ง ๋ชจ๋๋ก ๋ง์ด๊ทธ๋ ์ด์ ํ๋ ์์ ์ ์งํํ๋ค. ์ด ๊ณผ์ ์์ ๊ฒฐ์ ์๋จ์ ์ ์ฉ์นด๋๋ก ์ ํํ๋ฉด, ๊ธฐ์กด์ ์๋ ์ด๋์์ค(Inicis) ์ฝ๋ฐฑ ํ์ด์ง๊ฐ ์๋ก ํ์ํ๊ฒ๋์๋ค. (๊ธฐ์กด์๋ ํ ์คํ์ด๋จผ์ธ ๋ง ์ฌ์ฉํ๊ณ ์์๋ค.)
์ด๋์์ค์ ๊ฒฝ์ฐ, ๊ฒฐ์ ์ฝ๋ฐฑ์ด /api/payments/[id]/[paymentAgency]์ ๊ฐ์ API ๋ผ์ฐํฐ ๋ด๋ถ์์ ์คํ๋๋ค. ์ด ๊ตฌ์กฐ๋ ๊ธฐ์กด ํ ์คํ์ด๋จผ์ธ ์ ๋ฌ๋ฆฌ ์๋ฒ์ฌ์ด๋์์๋ง ๋์ํ๊ธฐ ๋๋ฌธ์ serverRuntimeConfig ํ๊ฒฝ๋ณ์๋ฅผ ์ฌ์ฉํ๊ณ ์๋ค.
โ serverRuntimeConfig๋?
serverRuntimeConfig๋ ์๋ฒ ์ฌ์ด๋์์๋ง ์ ๊ทผ ๊ฐ๋ฅํ ํ๊ฒฝ ๋ณ์ ์ค์ ๋ฐฉ๋ฒ์ด๋ค. ๋ค๋ง ํ์ฌ๋ ๋ ๊ฑฐ์๋ก ๊ฐ์ฃผ๋๊ณ ์์ผ๋ฉฐ, Next.js๋ฅผ standalone ๋ชจ๋๋ก ๋น๋ํ ๊ฒฝ์ฐ ๋น๋์์ ์ ๊ฐ์ผ๋ก ๊ณ ์ ๋๋ค. ๋ํ React server components์์๋ ์๋ํ์ง์๊ธฐ ๋๋ฌธ์ ์ด ๊ฒฝ์ฐ์๋ environment variables ์ฌ์ฉ์ด ๊ถ์ฅ๋๋ค.
// next.config.js
module.exports = {
serverRuntimeConfig: {
// ์๋ฒ์ฌ์ด๋์์๋ง ์คํ
mySecret: 'secret',
secondSecret: process.env.SECOND_SECRET, // Pass through env variables
},
publicRuntimeConfig: {
// ์๋ฒ & ํด๋ผ์ด์ธํธ ๋ชจ๋ ์คํ ๊ฐ๋ฅ
staticFolder: '/static',
},
}
// index.tsx
import getConfig from 'next/config'
import Image from 'next/image'
// Only holds serverRuntimeConfig and publicRuntimeConfig
const { serverRuntimeConfig, publicRuntimeConfig } = getConfig()
// Will only be available on the server-side
console.log(serverRuntimeConfig.mySecret)
// Will be available on both server-side and client-side
console.log(publicRuntimeConfig.staticFolder)
function MyImage() {
return (
<div>
<Image
src={`${publicRuntimeConfig.staticFolder}/logo.png`}
alt="logo"
layout="fill"
/>
</div>
)
}
export MyImage
๐งฉ ๋ฌธ์ ์ํฉ: ์๋ฒ์ฌ์ด๋ ํ๊ฒฝ๋ณ์ ๋๋ฝ
์ฌํผ ๋ฌธ์ ๊ฐ ๋์๋ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ์๋ฐ, ๊ณตํต๋ชจ๋๋ด์์ ๊ฒฐ์ ์น์ธ API๋ฅผ ์์ฒญํ๊ธฐ์ํ baseUrl์ ๋ค์์ฒ๋ผ ์ค์ ํ๋ค. ์ด ํจ์๋ ํ ์คํ์ด๋จผ์ธ (ํด๋ผ์ด์ธํธ์ฌ์ด๋)์ ์ด๋์์ค(์๋ฒ์ฌ์ด๋) ๋ชจ๋์์ ๋์ผํ๊ฒ ํธ์ถํ๊ณ ์๊ณ , ์ ์์ ์ผ๋ก ๋์ํ๊ณ ์์ด์ ๋ณ๋ค๋ฅธ ํ๊ฒฝ๋ณ์ ์ค์ ์ด ํ์์๋ค๊ณ ์๊ฐํ๋ค. ํ์ง๋ง DEVํ๊ฒฝ์์ ํ ์คํธ ์ค ๊ฒฐ์ ์น์ธ API๊ฐ ํธ์ถ๋์ง ๋ชปํ ํ์์ด ๋ฐ์ํ๊ณ datadog์์ ์๋ฌ๋ก๊ทธ๋ฅผ ํ์ธํด๋ณด๋ URL์ด ๋ค์๊ณผ ๊ฐ์ด ์๋ชป ์์ฑ๋๊ณ ์์๋ค.
// ํ๊ฒฝ๋ณ์๋ฅผ ์ ๋๋ก ๋ถ๋ฌ์ค์ง ๋ชปํ๋ ์ฝ๋
const baseUrl = serverRuntimeConfig?.API_GATEWAY_URL ?? process.env.PAYMENT_PROXY_PATH
const url = `${baseUrl}/externals/v1/payments/...`
TypeError: Failed to parse URL from ${PAYMENT_PROXY_PATH}/tour-billing/externals/v1/payments/...
PAYMENT_PROXY_PATH๋ ๋จ์ํ๊ฒ basePath/api routes์๊ณ , ์ฒ์์ ์ด๊ฒ ์ ์๋ฌ๊ฐ ๋ฐ์ํ๋์ง ์๋ฌธ์ด์์ง๋ง ๊ฒฐ๊ตญ ์์ธ์ ์ด ์ฝ๋๊ฐ ์๋ฒ์ฌ์ด๋์์ ์คํ๋๋ฉด์ ํธ์คํธ ์ ๋ณด๊ฐ ๋๋ฝ๋ ์ํ๋ก fetch๋ฅผ ์๋ํ ๊ฒ์ด์๋ค.
๐ง ํด๊ฒฐ ๋ฐฉ๋ฒ: apiGatewayUrl ํ๊ฒฝ๋ณ์ ๋ช ์
// ํ๊ฒฝ๋ณ์๋ฅผ ์ค์ ํ๋ ํจ์
export const withPaymentSdkEnv =
(options: WithPaymentSdkEnvOptions) =>
(nextConfig = {}) => {
const env = {}
return {
...nextConfig,
env,
serverRuntimeConfig: {
...env,
API_GATEWAY_URL: options.apiGatewayUrl
}, // ๋๋ฉ์ธ์์ apiGatewayUrl๋ฅผ ๋ฃ์ด์ฃผ์ง์์ PAYMENT_PROXY_PATH๋ฅผ ๋ฆฌํดํ์๋ค.
}
}
ํด๋ผ์ด์ธํธ์์ ํธ์ถํ๊ฒ๋๋ฉด web-gateway๋ฅผ ๊ฑฐ์น๊ธฐ๋๋ฌธ์ ํธ์คํธ ์์ด๋ PAYMENT_PROXY_PATH๋ฅผ ํตํด proxy ํธ์ถ์ด ๊ฐ๋ฅํ๋ค. ํ์ง๋ง ์ด๋์์ค ๊ฒฐ์ ์ฝ๋ฐฑ์ ์๋ฒ์ฌ์ด๋์์ ์คํ๋๋ฉฐ, web-gateway๋ฅผ ๊ฑฐ์น์ง์๊ธฐ๋๋ฌธ์ fetch์ ํธ์คํธ๊ฐ ๋๋ฝ๋ ๊ฒฝ๋ก๊ฐ ์์ฑ๋ ๊ฒ์ด์๋ค.
์ต์ข
์ ์ผ๋ก๋ ํ๊ฒฝ ๋ณ์์ apiGatewayUrl ๊ฐ์ ๋ช
์์ ์ผ๋ก ์ถ๊ฐํ๊ณ ,
- ์ด๋์์ค(์๋ฒ) ๊ฒฐ์ ์ →
API_GATEWAY_URL์ฌ์ฉ (ํธ์คํธ ํฌํจ) - ํ ์คํ์ด๋จผ์ธ (ํด๋ผ์ด์ธํธ) ๊ฒฐ์ ์ →
PAYMENT_PROXY_PATH์ฌ์ฉ (path๋ง ์ฌ์ฉ)
์ผ๋ก ์ฒ๋ฆฌํ์ฌ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ค.
โ ์ ๋ฆฌํ๋ฉฐ
์ด๋ฒ ์ด์๋ฅผ ํตํด fetch ํธ์ถ ์ ํ์ฌ ์ฝ๋๊ฐ ์๋ฒ์ฌ์ด๋์ธ์ง ํด๋ผ์ด์ธํธ์ฌ์ด๋์ธ์ง ๋ช ํํ ๊ตฌ๋ถํ๋ ์ต๊ด์ ์ค์์ฑ์ ๋ค์๊ธ ๊นจ๋ฌ์๋ค.
ํนํ API ํต์ ์์ ํ๊ฒฝ ๋ณ์ ์ฒ๋ฆฌ ๋ฐฉ์์ ์ฌ์ด๋์ ๋ฐ๋ผ ์ ํ ๋ค๋ฅด๊ฒ ์๋ํ ์ ์์ผ๋ฏ๋ก,ํ๊ฒฝ๋ณ์(serverRuntimeConfig, process.env, publicRuntimeConfig)๋ณ ๊ฐ๊ฐ์ ์ฐ์์๋ฅผ ์ ์ดํดํ๊ณ ์ ์ ํ ์ฌ์ฉํด์ผ ํ๋ค๊ณ ๋๊ผ๋ค.
๋๊ธ