# Axios for Nuxt
@nuxtjs/axios (opens new window) ๋ชจ๋์ Nuxt์ ์ฐ๋ํด์ ์์์ค์ค(Axios)๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณตํ๊ณ ์์ต๋๋ค. ์์ผ๋ก ์ด ๊ธ์์ ์ธ๊ธ๋ $axios
๋ Nuxt์ฉ ์์์ค์ค ์ธ์คํด์ค๋ฅผ ๋ปํฉ๋๋ค.
# ์ฃผ์ ํน์ง
- ์ต์ ์ ํตํด ๋ฐํ์ ํ๊ฒฝ(์๋ฒ, ํด๋ผ์ด์ธํธ)์ ๋ฐ๋ผ ์ฌ์ฉํ ๊ธฐ๋ณธ URL(Base URL)์ ์ง์ ํ ์ ์์ต๋๋ค.
- ์ต์ ์ ํตํด @nuxtjs/proxy (opens new window)์ ์ฐ๊ณํ์ฌ ํ๋ก์(Proxy (opens new window))๋ฅผ ์ฝ๊ฒ ํ์ฉํ ์ ์์ต๋๋ค.
- ์ต์ ์ ํตํด axios-retry (opens new window)์ ์ฐ๊ณํ์ฌ ๋น๋๊ธฐ ์์ฒญ ์คํจ์ ๋ฐ๋ฅธ ์ฌ์ ์ก ์ต์ ์ ์ฝ๊ฒ ์ค์ ํ ์ ์์ต๋๋ค.
- Nuxt์ ํ๋ก๊ทธ๋ ์ค ๋ฐ(Progress Bar (opens new window))์ ์๋์ผ๋ก ์ฐ๋๋ฉ๋๋ค.
- ํฌํผ ๋ฉ์๋๋ฅผ ํตํด
$axios
์ ์ธํฐ์ ํฐ, ํ ํฐ, ํค๋, ๊ธฐ๋ณธ URL์ ์ฝ๊ฒ ์ค์ ํ ์ ์์ต๋๋ค. - ํ๋ฌ๊ทธ์ธ์ ํตํด ์ปค์คํ
$axios
๋ฅผ Vue ์ธ์คํด์ค์ ์ฃผ์ (Inject) ํ ์ ์์ต๋๋ค.
# ์ค์น ๋ฐ ๋ฑ๋ก
Nuxt ํ๋ก์ ํธ๋ฅผ ์ค์นํ ๋ ์๋์ ๊ฐ์ด Axios ์ต์ ์ ์ ํํ๋ฉด ํจํค์ง ์ค์น๋ถํฐ ๋ชจ๋ ๋ฑ๋ก๊น์ง ์๋์ผ๋ก ์งํ๋ฉ๋๋ค.
์ด๋ฏธ ํ๋ก์ ํธ๋ฅผ ์ค์นํ ์ํ๋ผ๋ฉด ์๋์ ๋ฐฉ๋ฒ์ผ๋ก ํจํค์ง ์ค์น์ ๋ชจ๋ ๋ฑ๋ก์ ์งํํ์๋ฉด ๋ฉ๋๋ค.
npm install @nuxtjs/axios
// nuxt.config.js
export default {
modules: ["@nuxtjs/axios"],
};
# ๊ธฐ๋ณธ ํ์ฉ๋ฒ
ํจํค์ง ์ค์น์ ๋ชจ๋ ๋ฑ๋ก์ด ๋๋๋ฉด VueComponent ์ธ์คํด์ค์ context์ ๋ฑ๋ก์ด ๋๋ฏ๋ก ์๋์ ๊ฐ์ด ์ฌ์ฉํ ์ ์์ต๋๋ค.
<script>
export default {
async asyncData({ $axios }){
const { data } = await $axios.get(...);
...
},
async fetch(){
const { data } = await this.$axios.get(...);
...
},
}
</script>
TIP
$axios
์๋ต(Response) ๊ฐ์ data
๊ตฌ์กฐ ๋ถํด ํ ๋น์ด ๋ฒ๊ฑฐ๋ก์ธ ๊ฒฝ์ฐ, ์๋์ ๊ฐ์ด $axios
์ ์์ฒญ(Request) ๋ฉ์๋ ์์ $
๋ฅผ ๋ถ์ฌ์ ํธ๋ฆฌํ๊ฒ data
์์ฑ ๊ฐ์ ๋ฐ์ ์ฌ ์ ์์ต๋๋ค. ์ฐธ์กฐ (opens new window)
async fetch(){
console.log(
JSON.stringify(await this.$axios.$get('/products'))
=== JSON.stringify((await this.$axios.get('/products')).data)
) // true
}
# ์ต์
Nuxt ์ค์ ํ์ผ์ ์ต์
์ ๋ช
์ํ์ฌ $axios
์ ํ๊ฒฝ ์ค์ (Configuration)์ ํ ์ ์์ต๋๋ค. ๋ณธ๋ฌธ์์๋ ์์ฃผ ์ฐ์ด๋ ์ต์
๋ค ์์ฃผ๋ก ์ค๋ช
ํ๊ฒ ์ต๋๋ค.
TIP
$axios
์ ํ๊ฒฝ ์ค์ ์ ์ด ๋ ์ฐจ๋ก์ ๊ฑธ์ณ ์ผ์ด๋ฉ๋๋ค. Nuxt ์ค์ ํ์ผ์ ํตํด์ ์ค์ ์ด ์ฐ์ ์ ์ฉ๋๊ณ ๋ ๋ฒ์งธ๋ก๋ ํ๋ฌ๊ทธ์ธ์ ํตํด ์ค์ ์ด ์ถ๊ฐ ์ ์ฉ๋ฉ๋๋ค.
# Host, Port, Prefix
ํธ์คํธ(Host), ํฌํธ(Port), ํ๋ฆฌํฝ์ค(Prefix)๋ ์ดํ์ ์ธ๊ธํ baseURL
๊ณผ browserBaseURL
์ ๋ํดํธ ๊ฐ์ ์ฌ์ฉ๋๋ ๊ฐ์
๋๋ค. ์๋์ ๊ฐ์ด Nuxt ์ค์ ํ์ผ์ ๋ช
์ํ ์ ์์ต๋๋ค.
// nuxt.config.js
export default {
// $axios์ baseURL์ https://example.com:9000/๋ก ์ค์
axios: {
host: "https://example.com",
port: "9000",
prefix: "/",
},
};
๋๋ ํ๊ฒฝ ๋ณ์์ API_HOST
, API_PORT
, API_PREFIX
๋ก ๊ฐ์ ์ง์ ํ ์ ์์ต๋๋ค.
// .env
API_HOST=https://example.com
API_PORT=9000
API_PREFIX=/
# BaseURL
$axios
์ baseURL
์์ฑ์ ์๋ฒ ์ฌ์ด๋์์ ์์ฒญ์ ๋ณด๋ผ ๋ ๊ธฐ๋ณธ URL์ด ๋๋ ๊ฐ์
๋๋ค. ๋ํดํธ ๊ฐ์ http://[HOST]:[PORT][PREFIX] ๊ฐ์ผ๋ก ์์์ ์ธ๊ธํ๋ ํธ์คํธ, ํฌํธ, ํ๋ฆฌํฝ์ค๊ฐ ์ฌ์ฉ๋ฉ๋๋ค. ๋๋ ์๋์ ๊ฐ์ด ์ง์ baseURL
์ ์ง์ ํ ์ ์์ต๋๋ค.
// nuxt.config.js
export default {
axios: {
baseURL: "http://localhost:8080/modules",
},
};
๋๋ ํ๊ฒฝ ๋ณ์์ API_URL
๋ก ๊ฐ์ ์ง์ ํ ์ ์์ต๋๋ค.
// .env
API_URL=http://localhost.com:8080/modules
# BrowserBaseURL
browserBaseURL
์์ฑ์ ํด๋ผ์ด์ธํธ ์ฌ์ด๋์์ ์์ฒญ์ ๋ณด๋ผ ๋ ๊ธฐ๋ณธ URL์ด ๋๋ ๊ฐ์
๋๋ค. ์์์ ์ธ๊ธํ baseURL
์ ๋ํดํธ ๊ฐ์ผ๋ก ๊ฐ์ง๋๋ค. ์๋์ ๊ฐ์ด ์ง์ browserBaseURL
์ ์ง์ ํ ์ ์์ต๋๋ค.
// nuxt.config.js
export default {
axios: {
browserBaseURL: "https://learnNuxt.com:8080/modules",
},
};
๋๋ ํ๊ฒฝ ๋ณ์์ API_URL_BROWSER
๋ก ๊ฐ์ ์ง์ ํ ์ ์์ต๋๋ค.
// .env
API_URL_BROWSER=https://learnNuxt.com:8080/modules
# Proxy
@nuxtjs/axios
๋ฅผ ์ค์นํ๋ฉด ์์กด์ฑ(Dependency)์ ์ํด์ ์๋์ผ๋ก @nuxtjs/proxy
(opens new window)๊ฐ ์ค์น๋ฉ๋๋ค. ๋ค์๊ณผ ๊ฐ์ด axios.proxy
๋ฅผ true
๋ก ์ค์ ํ๋ฉด $axios
์ ํ๋ก์ ์ฌ์ฉ์ด ๊ฐ๋ฅํด์ง๋๋ค.
// nuxt.config.js
export default {
axios: {
proxy: true,
},
proxy: {
"/api/": "http://api.example.com",
"/api2/": "http://api.another-website.com",
},
};
# Retry
@nuxtjs/axios
๋ฅผ ์ค์นํ๋ฉด ์์กด์ฑ์ ์ํด์ ์๋์ผ๋ก axios-retry
(opens new window)๊ฐ ์ค์น๋ฉ๋๋ค. ์ด ๋ชจ๋์ ์ ์ฉํ๋ฉด $axios
์์ฒญ ์คํจ ์ ์๋์ผ๋ก ๊ฒฐ๊ณผ๋ฅผ ๊ฐ๋ก์ฑ์ ๋ค์ ์์ฒญ์ ๋ณด๋
๋๋ค. Nuxt ์ค์ ํ์ผ์ axios.retry
๋ฅผ true
๋ก ์ค์ ํ๊ฑฐ๋ retryOptions
(opens new window)๋ฅผ ์ง์ ํ๋ฉด ์์ฒญ ์คํจ์ ๋ฐ๋ฅธ ์๋ ์ฌ์์ฒญ์ด ๊ฐ๋ฅํด์ง๋๋ค. ์ฐธ๊ณ ๋ก ์ฌ์ ์ก ํ์์ ๋ํดํธ๋ 3ํ์
๋๋ค.
// nuxt.config.js
export default {
axios: {
retry: {
retries: 4, // ์ต๋ ์ฌ์ ์ก ํ์ 4ํ
shouldResetTimeout: true, // ์ฌ์ ์ก ๊ฐ ํ์์์์ ๋ฆฌ์
ํ๊ธฐ
retryDelay: (retry) => {
return retry * 100; // ์ฌ์ ์ก ํ์ * 0.1์ด๋งํผ ์ฌ์ ์ก ์์ ์๊ฐ์ ์ง์ฐ์ํค๊ธฐ
},
retryCondition: (error) => err.response.status === 429, // ์๋ฒ ํผ์ก์ด ์ผ์ด๋ฌ์ ๊ฒฝ์ฐ์๋ง ์ฌ์ ์กํ๊ธฐ
},
},
};
# Progress
Nuxt์ ํ๋ก๊ทธ๋ ์ค ๋ฐ(Progress Bar)์ ์ฐ๋ํด์ ์์ฒญ ๋์ ๋ก๋ฉ ๋ฐ(Loading Bar)๋ฅผ ๋ณด์ฌ์ค๋๋ค. ์ด ์ค์ ์ ๋ํดํธ๋ก ์ค์ ๋์ด ์๊ธฐ ๋๋ฌธ์ ๋ก๋ฉ ๋ฐ๋ฅผ ๋ณด์ฌ์ฃผ๊ณ ์ถ์ง ์๋ค๋ฉด Nuxt ์ค์ ํ์ผ์ ์ด๋ฅผ ๋ช ์ํด์ผ ํฉ๋๋ค.
// nuxt.config.js
export default {
axios: {
progress: false, // ๋ก๋ฉ ๋ฐ๋ฅผ ์ฌ์ฉํ์ง ์์
},
};
๊ฐ๋ณ ์์ฒญ์๋ง ์ ์ฉํ๊ณ ์ถ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์ฌ์ฉํฉ๋๋ค.
this.$axios.$get("...", { progress: false });
# ๊ทธ ์ธ ์ต์
์์์ ์ธ๊ธ๋์ง ์์ ์ต์ ๋ค์ ์๋์ ํ์ ๊ณผ ๊ณต์ ๋ฌธ์ (opens new window)๋ฅผ ์ฐธ์กฐํด ์ฃผ์ธ์.
# ํฌํผ ๋ฉ์๋
$axios
์ ๊ธฐ๋ณธ URL, ํค๋, ํ ํฐ, ์ธํฐ์
ํฐ๋ฅผ ์ค์ ํ๊ธฐ ์ํด์ ๋ค ์ข
๋ฅ์ ํฌํผ ๋ฉ์๋๊ฐ ์ ๊ณต๋ฉ๋๋ค. ์ด๋ฒ ์น์
์์๋ ๊ธฐ๋ณธ URL, ํค๋, ํ ํฐ์ ์ค์ ํ๋ ๋ฉ์๋๋ง ๋ค๋ฃจ๊ณ ์ธํฐ์
ํฐ ๊ด๋ จ ๋ฉ์๋๋ ํ๋ฌ๊ทธ์ธ ์น์
์ ์ธํฐ์
ํฐ ์ถ๊ฐํ๊ธฐ์์ ๋ค๋ค๋ณด๊ฒ ์ต๋๋ค.
# setBaseURL
$axios
์ ๊ธฐ๋ณธ URL์ ์ค์ ํฉ๋๋ค.
// ํด๋ผ์ด์ธํธ, ์๋ฒ ๋ชจ๋์์ ์ฌ์ฉํ ์ ์๋ ๊ธฐ๋ณธ URL ์ค์
$axios.setBaseURL("http://api.example.com");
// ํด๋ผ์ด์ธํธ ์ฌ์ด๋์์๋ง ์ฌ์ฉํ ์ ์๋ ๊ธฐ๋ณธ URL ์ค์
if (process.client) {
$axios.setBaseURL("http://api.example.com");
}
// ์๋ฒ ์ฌ์ด๋์์๋ง ์ฌ์ฉํ ์ ์๋ ๊ธฐ๋ณธ URL ์ค์
if (process.server) {
$axios.setBaseURL("http://api.example.com");
}
# setHeader
$axios
์ ์์ฒญ ํค๋๋ฅผ ์ค์ ํฉ๋๋ค.
// $axios๋ก ์์ฒญ์ ๋ณด๋ผ ๋๋ง๋ค ํค๋์ 'Authorizaion : 123'์ด ๋ฑ๋ก๋จ
$axios.setHeader("Authorization", "123");
// 'Authorization' ํค๋์ ์๋ก์ด ๊ฐ ๋ฎ์ด์ฐ๊ธฐ
$axios.setHeader("Authorization", "456");
# setToken
$axios
์ ์์ฒญ ํค๋์ธ Authorization
๊ฐ์ ์ค์ ํฉ๋๋ค.
// $axios๋ก ์์ฒญ์ ๋ณด๋ผ ๋๋ง๋ค ํค๋์ 'Authorizaion : 123'์ด ๋ฑ๋ก๋จ, ์๋ก์ด ๊ฐ์ผ๋ก ๋ฎ์ด์ฐ๊ธฐ๋ ๊ฐ๋ฅ
$axios.setToken("123");
// ํ ํฐ์ ์ธ์ฆ ์คํด ์ง์ ๊ฐ๋ฅ, 'Authorization : Bearer 123'์ด ๋ฑ๋ก๋จ
$axios.setToken("123", "Bearer");
// ํ ํฐ์ ์ฒจ๋ถํ ์์ฒญ ๋ฉ์๋ ์ ํ ๊ฐ๋ฅ, post, put, delete ์์ฒญ์ ๋ณด๋ผ ๊ฒฝ์ฐ๋ง ํค๋์ 'Authorization : Bearer 123'์ด ๋ฑ๋ก๋จ
$axios.setToken("123", "Bearer", ["post", "put", "delete"]);
WARNING
$axios
์ ์ค์ ์ ๋ฐ๊ฟ ๊ฒฝ์ฐ ๊ธ๋ก๋ฒํ๊ฒ ์ ์ฉ๋๋ฏ๋ก ์๋์น ์์ ๋์์ ๋ง๊ธฐ ์ํด ํฌํผ ๋ฉ์๋๋ฅผ ์ปดํฌ๋ํธ์์ ํ์ฉํ๊ธฐ๋ณด๋จ ํ๋ฌ๊ทธ์ธ์์ ํ์ฉํ๋ ๊ฒ์ ์ถ์ฒํฉ๋๋ค.
# ํ๋ฌ๊ทธ์ธ
ํ๋ฌ๊ทธ์ธ์ ํตํด $axios
์ ํฌํผ ๋ฉ์๋๋ก ์ค์ ์ ์ถ๊ฐ/๋ณ๊ฒฝํ๊ฑฐ๋, ์๋ก์ด ์์์ค์ค ์ธ์คํด์ค๋ฅผ ์์ฑํด์ Nuxt์ ์ฃผ์
ํ ์ ์์ต๋๋ค.
Nuxt์ ๋ฑ๋ก๋ $axios
๋ฅผ ํ์ฉํ๊ธฐ ์ํด์๋ Nuxt ์ค์ ํ์ผ์ plugins
์์ฑ์ $axios
๋ฅผ ์กฐ์ํ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ์ ๋ฑ๋กํด์ผ ํฉ๋๋ค.
# ์ค์ ๋ณ๊ฒฝํ๊ธฐ(overwrite)
์ฐธ๊ณ ๋ก $axios
๋ ์ต์
์ ๋ช
์ํ ์ค์ ์ด ์ด๋ฏธ ์ ์ฉ๋ ์ํ์ด๊ณ ํ๋ฌ๊ทธ์ธ์ ํตํด ๊ธฐ์กด์ ์ค์ ์ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค. ์๋๋ ๊ทธ ์์์
๋๋ค.
// nuxt.config.js
export default {
plugins: ["@/plugins/api"],
axios: {
baseURL: "http://localhost:5000",
},
publicRuntimeConfig: {
axios: {
browserBaseURL: "http://localhost:4000",
},
},
privateRuntimeConfig: {
axios: {
baseURL: "http://localhost:3000",
},
},
};
// plugins/api.js
export default function({ $axios }) {
if (process.server) {
$axios.setBaseURL("http://localhost:8000");
}
if (process.client) {
$axios.setBaseURL("http://localhost:9000");
}
}
์ต์
์ผ๋ก ๊ธฐ๋ณธ URL์ ์ค์ ํ๋๋ผ๋ ํ๋ฌ๊ทธ์ธ์ ํตํด ๋ณ๊ฒฝ์ด ๊ฐ๋ฅํฉ๋๋ค. ์์ ์์์์๋ ์ต์ข
์ ์ผ๋ก ํด๋ผ์ด์ธํธ ์ฌ์ด๋์์ $axios
์ ๊ธฐ๋ณธ URL์ ํฌํธ 8000๋ฒ์ด ๋๊ณ ์๋ฒ ์ฌ์ด๋์์๋ ํฌํธ 9000๋ฒ์ด ๋ฉ๋๋ค.
# ์ธํฐ์ ํฐ ์ถ๊ฐํ๊ธฐ
๋น๋๊ธฐ ๋ฐ์ดํฐ ํต์ ๊ณผ์ ์์ ์์ฒญ ๋ฐ์, ์๋ต ์์ ๋ฑ์ ๋ฐ์ํ์ฌ ํจ์๋ฅผ ํธ์ถํ๋ ์ธํฐ์ ํฐ๋ฅผ ์ถ๊ฐํ ์ ์์ต๋๋ค. ์๋๋ ์ธํฐ์ ํฐ์ ์ฌ์ฉ๋ ์ ์๋ ํฌํผ ๋ฉ์๋๋ค์ ์์ ๋๋ค. ํฌํผ ๋ฉ์๋๋ค์ ํจ์๋ฅผ ๋ฑ๋กํด๋๋ฉด ํน์ ์ํฉ ๋ฐ์ ์ ํจ์๋ฅผ ํธ์ถํฉ๋๋ค.
onRequest(config => {...})
: ์์ฒญ์ด ๋ฐ์ํ๋ฉด ํจ์ ํธ์ถonResponse(response => {...})
: ์๋ต์ ์์ ํ๋ฉด ํจ์ ํธ์ถonError(error => {...})
: ์์ฒญ/์๋ต ์๊ด์์ด ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด ํจ์ ํธ์ถonRequestError(error => {...})
: ์์ฒญ ์คํจ๊ฐ ๋ฐ์ํ๋ฉด ํจ์ ํธ์ถonResponseError(error => {...})
: ์๋ต ์คํจ๊ฐ ๋ฐ์ํ๋ฉด ํจ์ ํธ์ถ
์๋๋ ์ธํฐ์ ํฐ ์ถ๊ฐ ์์์ ๋๋ค.
// plugins/api.js
export default function({ $axios, redirect }) {
$axios.onRequest((config) => {
console.log("Making request to " + config.url); // ์์ฒญ ๋๋ง๋ค url ์ถ๋ ฅ
});
$axios.onError((error) => {
const code = parseInt(error.response && error.response.status);
if (code === 400) {
redirect("/400"); // 400 ์๋ฌ ๋ฐ์์ /400์ผ๋ก ๋ฆฌ๋ค์ด๋ ํธ
}
});
}
# ์ปค์คํ axios ์ธ์คํด์ค ์ฃผ์
์์์ค์ค ์ธ์คํด์ค๋ฅผ ์๋ก ์์ฑํด์ $axios
์ฒ๋ผ context
๋ VueComponent
์ธ์คํด์ค์์ ์ฌ์ฉํ ์ ์๋๋ก ์์์ค์ค ์ธ์คํด์ค๋ฅผ ์ฃผ์
ํ ์ ์์ต๋๋ค.
// plugins/api.js
export default function({ $axios }, inject) {
// ์๋ก์ด ์์์ค์ค ์ธ์คํด์ค ์์ฑ
const api = $axios.create({
headers: {
common: {
Accept: "text/plain, */*",
},
},
});
// ์ธ์คํด์ค์ ๊ธฐ๋ณธ URL ๋ณ๊ฒฝ
api.setBaseURL("https://my_api.com");
// context์ ์ฃผ์
, $api ํํ๋ก ํธ์ถ ๊ฐ๋ฅ
inject("api", api);
}
์์ ๊ฐ์ด ํ๋ฌ๊ทธ์ธ์ ํตํด $api
๋ฅผ ์ฃผ์
ํ๋ฉด ์๋์ ๊ฐ์ด ์ฌ์ฉ์ด ๊ฐ๋ฅํด์ง๋๋ค.
<script>
export default {
async asyncData({ $api }){
const { data } = await $api.get(...);
...
},
async fetch(){
const { data } = await this.$api.get(...);
...
},
}
</script>
# ์ฐธ๊ณ ์๋ฃ
โ Meta Tags Introduction ๐ โ