æ¬èšäºã¯ãNuxt / UnJSã¢ããã³ãã«ã¬ã³ããŒã®21æ¥ç®ã®èšäºã§ãð ð
ã¯ããã«
ãªãŒãã€ãã§ããïŒð±ãçããããã«ã¡ã¯ã
èªåã¯æ®æ®µãæ¥åã§Nuxt3ã䜿ã£ãŠããã³ããšã³ãã®éçºãããŠããŸãã
Nuxt3ã§ã¯ã$fetch
ãšãããã«ããŒã䜿ã£ãŠãofetchãšããHTTPã¯ã©ã€ã¢ã³ãã©ã€ãã©ãªãåŒã³åºããŸãã
ããã«ãNuxtã®useFetch
ãuseAsyncData
ãªã©ã®ããŒã¿ååŸçšã³ã³ããŒã¶ãã«ãããã®ofetchãããŒã¹ã«ããŠããŸãã
ãããªNuxtã®ããŒã¿éä¿¡ã§éèŠãªåœ¹å²ãæ ãofetchã§ãããå®éã©ããªãšããã䟿å©ãªã®ããã©ããªæ©èœãæã£ãŠãããèªåã§ããããã£ãŠããªãã£ããããæšæºã®fetch APIãšæ¯èŒãã€ã€ããã®é åãæ¢ã£ãŠã¿ãŸããïŒ
ofetchãšã¯ïŒ
ofetchã¯HTTPã¯ã©ã€ã¢ã³ãã©ã€ãã©ãªã§ããAPIã«ãªã¯ãšã¹ããéã£ãŠããŒã¿ãååŸãããããã®ã«äœ¿ããŸããåçã®æ©èœãæã€ã©ã€ãã©ãªãšããŠæåãªãã®ã«ã¯Axiosãªã©ããããŸãã
ofetchã¯UnJSãšããJavaScriptã®ã©ã€ãã©ãªçŸ€ã®ã²ãšã€ã«ãªããŸãã2024幎12ææç¹ã§UnJSã®ã©ã€ãã©ãªã¯60以äžãããååãèããããšã®ããã©ã€ãã©ãªãäžã«ã¯ãããããããŸããã
UnJSã®éçºã«ã¯Nuxtã®éçºã¡ã³ããŒãæ·±ãæºãã£ãŠãããofetch以å€ã«ããNuxt3ã®æ ¹å¹¹ãæ
ã£ãŠããã©ã€ãã©ãªãUnJSã«ã¯è€æ°ãããŸãã
äœã䟿å©ãªã®ïŒ
ããã§ã¯æ©éãofetchã®æ©èœãèŠãŠãããŸãããïŒåºæ¬çãªäœ¿ãæ¹ã¯ä»¥äžã§ãã
await ofetch('ãªã¯ãšã¹ãURL', ãªãã·ã§ã³èšå®ããããªããžã§ã¯ã)
1. èªåã§ã¬ã¹ãã³ã¹ããŒã¿ãå€æããŠãããïŒ
JSON圢åŒã®ã¬ã¹ãã³ã¹ãååŸãããªããžã§ã¯ãã«å€æã䜿çšãããããã¯fetchã®ä»£è¡šçãªäœ¿ãæ¹ã ãšæããŸãã
ofetchã¯ã¬ã¹ãã³ã¹ã®åœ¢åŒãåæããŠãèªåã§å€æããŠãããŸãã
äŸãã°ãæšæºã®fetch APIã§ã¯JSON圢åŒã®ããŒã¿ãååŸãããå Žåã以äžã®ããã«å€æããªããŠã¯ãããŸãããâŠâŠ
const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
const json = await response.json();
ofetchã䜿ããšä»¥äžã ãã§æžã¿ãŸãã
const response = await ofetch('https://jsonplaceholder.typicode.com/posts/1');
ã¡ãªã¿ã«ãä»åã¯ãã¹ãçšã®ãšã³ããã€ã³ããšããŠãããŒããŒã¿ãè¿ãJSON PlaceholderãšãããµãŒãã¹ã䜿ã£ãŠããŸããã³ãŒããåãããšå®éã«ããŒã¿ãååŸã§ããŸãïŒ
JSONãžã®å€æã¯ãdestrãšããããããŸãUnJSã®ã©ã€ãã©ãªã䜿ã£ãŠè¡ã£ãŠããããã§ãã
JSON以å€ãžã®å€æãã§ããŸããtextãblobãarrayBufferãªã©ã®åœ¢åŒã«å¯Ÿå¿ããŠããŸãã
await ofetch('url', { contentType: 'blob' })
ã®ããã«ã䜿çšæã«æ瀺çã«ã©ã®çš®é¡ã®ããŒã¿ãšããŠå€æãããæ瀺ããããšãã§ããŸãããæå®ããªãã£ãå Žåã¯ãã¬ã¹ãã³ã¹ããããŒã®Content-Typeããæ
å ±ãååŸããŠãããŸãã
2. ããŒã¿éä¿¡æãèªåã§ããŒã¿ãå€æããŠãããïŒ
éã«ãJSONããªã¯ãšã¹ãããã£ã«ä»äžããŠããŒã¿ãéä¿¡ãããå ŽåããããšæããŸãã
ãã®å Žåãæšæºã®fetch APIã ãšä»¥äžã®ããã«æžããŸãã
await fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
body: JSON.stringify({
title: 'Title',
body: 'Hello, world!',
userId: 1,
}),
headers: {
'Content-type': 'application/json',
},
})
JSON.stringify()
ã§ãªããžã§ã¯ããJSONæååã«å€æããå¿
èŠããããŸãã
ofetchã¯ãtoJSON()
ã¡ãœãããæã€ãªããžã§ã¯ããbodyã«æž¡ããããšãèªåã§JSON.stringfy()
ã§ããŒã¿ãå€æããŠãããŸããããã«ãPOSTã»PUTã»PATCHã¡ãœããã䜿çšããŠãããšãã¯ãheaderã«Content-Type: "application/json"
ïŒãšãaccept: "application/json"
ïŒãä»äžããŠãããŸãã
äžèšã³ãŒããšåãããšã以äžã§ã§ããã®ã§ãã
await ofetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
body: {
title: 'Title',
body: 'Hello, world!',
userId: 1,
},
});
ç°¡æœã§ããâºïž
3. ã¹ããŒããªãšã©ãŒãã³ããªã³ã°
APIã䜿çšãããšãã¯ããšã©ãŒãè¿ã£ãŠãããšãã®åŠçãäžç·ã«æžãããšãå€ããšæããŸãã
ofetchã§ã¯ãšã©ãŒãã³ããªã³ã°ãç°¡åã«ã§ããŸãããããŠãã®åŠçã«äžå·¥å€«ãããŠããŸãïŒð
APIéä¿¡ã§èµ·ããã2çš®é¡ã®ãšã©ãŒ
APIéä¿¡ã§çºçããããšã©ãŒã¯2çš®é¡ãããŸãããããã¯ãŒã¯ãšã©ãŒãšããµãŒããŒãåŠçããçµæãšããŠã®ãšã©ãŒïŒã¬ã¹ãã³ã¹ãšã©ãŒïŒã§ãã
åè
ã¯ããããéä¿¡ã«å€±æããŠããŠãåŸè
ã¯éä¿¡ã«ã¯æåããŠããããã¬ã¹ãã³ã¹å
容ãšããŠãšã©ãŒãè¿ã£ãŠããŠãããšããéãã§ãã
æšæºã®fetch APIã®å Žå
æšæºã®fetch APIã®å Žåããã®2ã€ã®ãšã©ãŒãæ€ç¥ããæ¹æ³ãç°ãªããŸãã
ãŸããããã¯ãŒã¯ãšã©ãŒã§ãããtry/catchæ§æããPromise
ãªããžã§ã¯ãã®catch
ã¡ãœããã䜿ã£ãŠååŸããŸãã以äžã®ãããªã€ã¡ãŒãžã§ãã
ïŒå®éã¯error
ã«å¯ŸããŠåãšã©ãŒãèµ·ãã£ããããã®ã§ãã€ã¡ãŒãžãã§ãïŒ
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts/10000');
// åŸç¶ã®åŠç...
} catch (error) {
// ãããã¯ãŒã¯ãšã©ãŒãæ€ç¥
console.error(error.message);
}
ãã®å Žåãéä¿¡ã«æåãã¬ã¹ãã³ã¹ãè¿ã£ãŠããŠããã°ãã¬ã¹ãã³ã¹ã®å 容ããšã©ãŒã§ãããšã©ãŒã¯ãã£ãããããŸãããæ£åžžãªã¬ã¹ãã³ã¹ãããšã©ãŒã¬ã¹ãã³ã¹ãã¯é¢ä¿ãªãã®ã§ãã
ã¬ã¹ãã³ã¹ãæ£åžžãåŠãã¯ã¹ããŒã¿ã¹ã³ãŒããåç
§ããããšã§ããããŸãã200çªå°ãæåã®ã¹ããŒã¿ã¹ã§ãã
ãããã¯ãfetch APIããè¿ãããResponse
ãªããžã§ã¯ãã®ok
ããããã£ãtrue
ã«ãªã£ãŠãããã§ãå€æå¯èœã§ãã以äžã®ãããªã€ã¡ãŒãžã§ãã
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts/10000');
if (!response.ok) {
// ã¬ã¹ãã³ã¹ãšã©ãŒã®å ŽååŠçãäžæ
console.error(`${response.status} - ${response.statusText}`);
return;
}
// åŸç¶ã®åŠç...
} catch (error) {
// ãããã¯ãŒã¯ãšã©ãŒãæ€ç¥
console.error(error.message);
}
以äžã®ããã«ãæšæºã®fetch APIã䜿ããšããšã©ãŒåŠçãããéšåã2ç®æã«åæ£ããŸãã
ãããã¯ãŒã¯ãšã©ãŒã®å Žåãšã¬ã¹ãã³ã¹ãšã©ãŒã®å Žåã§ç°ãªãåŠçãããå Žåã¯ç¹ã«åé¡ãªããããããŸããããå
±éã®åŠçãè¡ãå Žåã¯ããåé·ã§ããã
ofetchã®å Žå
ofetchã¯2ã€ã®ãšã©ãŒãåãããã«è¿ããŠãããŸããå
·äœçã«ã¯ãã©ã¡ãã®å ŽåãFetchError
ã¯ã©ã¹ãšããå
±éã®ã¯ã©ã¹ã䜿ã£ãŠãšã©ãŒãªããžã§ã¯ããçæããthrow
ããŠãããŸãã
åèïŒofetchã®ãœãŒã¹ã³ãŒãð
â»ã³ã¡ã³ãã¯èªåã§ä»ãå ãããã®ã§ã
// ...åç¥
try {
context.response = await fetch(
context.request,
context.options as RequestInit
);
} catch (error) {
context.error = error as Error;
if (context.options.onRequestError) {
await callHooks(
context as FetchContext & { error: Error },
context.options.onRequestError
);
}
return await onError(context); // ãšã©ãŒãªããžã§ã¯ããäœæãthrowããé¢æ°ãåŒã³åºã
} finally {
if (abortTimeout) {
clearTimeout(abortTimeout);
}
}
// ...äžç¥...
// â ã¹ããŒã¿ã¹ã³ãŒãã400~599ã®ç¯å²ã®ãã®ã§ããããã¿ãŠããã
// ã¬ã¹ãã³ã¹ãšã©ãŒãç¡èŠãããªãã·ã§ã³ãããããã§ãã(ignoreResponseErroréšå)
if (
!context.options.ignoreResponseError &&
context.response.status >= 400 &&
context.response.status < 600
) {
if (context.options.onResponseError) {
await callHooks(
context as FetchContext & { response: FetchResponse<any> },
context.options.onResponseError
);
}
return await onError(context); // ãšã©ãŒãcatchãããšããšåãåŠçãããŠããŸããïŒ
}
// åŸç¥...
ãããã¯ãŒã¯ãšã©ãŒã®å Žåãã¬ã¹ãã³ã¹ãšã©ãŒã®å Žåãã©ã¡ããåãåŠçãããŠããŸããïŒ
ã¡ãªã¿ã«ãcontext.options.onRequestError
ãcontext.options.onResponseError
ã¯ãåŸè¿°ãããã€ã³ã¿ãŒã»ãã¿ãŒããèšå®ãããŠããå Žåã®åŠçãè¡ã£ãŠããŸãã
ã¬ã¹ãã³ã¹ãšã©ãŒã§ããšã©ãŒãthrow
ããŠãããã®ã§ãcatch
ã§ãšã©ãŒãæ€ç¥ããããšãã§ããŸãã
ã³ãŒãã®ã€ã¡ãŒãžã¯æ¬¡ã®ãããªæãã§ãã
try {
const response = await ofetch('https://jsonplaceholder.typicode.com/posts/10000');
// åŸç¶ã®åŠç...
} catch (error) {
console.error(`${error.status} - ${error.statusText}`)
}
ã·ã³ãã«ã§ããð
åŠçããŸãšããããŠãèªã¿ããããªããŸããã
ãšã©ãŒæã«èªåã§åè©Šè¡ããŠããã
ã¡ãªã¿ã«ã§ãããç¹å®ã®ã¹ããŒã¿ã¹ã³ãŒããè¿ã£ãŠããå Žåããªã¯ãšã¹ããåè©Šè¡ããèšå®ãããããšãã§ããŸãã
ãªãã·ã§ã³èšå®ã§ãretry
ãªãã·ã§ã³ã«åè©Šè¡åæ°ã®äžéãæå®ããããšã§äœ¿çšã§ããŸãã
ïŒããã©ã«ãã§ãGETã¡ãœããã¯1ååè©Šè¡ãããã以å€ã®ã¡ãœããã¯åè©Šè¡ããªãèšå®ã«ãªã£ãŠããããã§ãïŒ
4. ã€ã³ã¿ãŒã»ãã¿ãŒã§ä»»æã®åŠçãæã¿èŸŒã
ofetchã®ã€ã³ã¿ãŒã»ãã¿ãŒãšåŒã°ããæ©èœã§ã¯ããªã¯ãšã¹ãæãã¬ã¹ãã³ã¹ãåãåã£ããšãããšã©ãŒãçºçãããšãããªã©ã®ã€ãã³ããçºçãããšãã«å®è¡ããåŠçãå®çŸ©ããããšãã§ããŸãã
äŸãã°ããªã¯ãšã¹ãã®éã«ããŠãŒã¶ãŒIDãã¯ãšãªãã©ã¡ãŒã¿ãŒã«å«ããåŠçãããããšãã¯ã以äžã®ããã«æžããŸãã
const response = await ofetch(
'https://jsonplaceholder.typicode.com/posts',
{
async onRequest({ request, options }) {
options.query = options.query || {};
options.query.userId = loginUser.id; // ãã°ã€ã³ããŠãããŠãŒã¶ãŒã®IDãå
¥ãæ³å®
},
}
);
æšæºã®fetch APIã«ã¯ã€ã³ã¿ãŒã»ãã¿ãŒã®ãããªæŠå¿µã¯ãªããšæããŸãã
ãªã¯ãšã¹ãæãã¬ã¹ãã³ã¹ãåãåã£ããšãã«æ¯åè¡ãããåŠçãããå Žåã¯äŸ¿å©ããã§ããïŒ
5. ããŒã¹URLã®èšå®ãããŠå ±éå
å€ãã®å Žåãåäžã¢ããªã±ãŒã·ã§ã³å
ã§ãªã¯ãšã¹ãããURLã®ãã¹ãéšåã¯å
±éã§ããæ¯ååãURLãèšè¿°ããã®ã¯åé·ã§ä¿å®æ§ãäœããªããŸãããã®éšåã®å
±éåã¯èªåã§ãããè¡ãããŠããã®ã§ã¯ãªãã§ããããã
ofetchã§ã¯ãããbaseURLãªãã·ã§ã³ãšããŠèšå®ã§ããããã«ããŠããŸãã
以äžã䜿çšäŸã§ããã¡ãªã¿ã«ããã®æ©èœã§ã¯URLã®ããŒã¹ãªã©ã®åŠçã«UnJSã®ufoã䜿ãããŠããŸãðž
const baseURL = 'https://jsonplaceholder.typicode.com';
const response = await ofetch('/posts/1', { baseURL });
äŸãèŠãŠãïŒæ¯åbaseURL
ã®ãªãã·ã§ã³ãèšå®ããã®ãããã©ããããªãâŠâŠïŒãšæã£ãæ¹ãããã£ãããã§ãããã
æåŸã«ãofetchã®ãªãã·ã§ã³èšå®ãå
±éåããããã®æ©èœã玹ä»ããŸãã
ä»»æã®èšå®ãããã©ã«ããšããŠãã€ofetchã®ãªããžã§ã¯ããäœæã䜿ãããšãã§ããŸããofetch.create()
ã䜿ã£ãŠäœæã§ããŸãã
const baseFetcher = ofetch.create({
baseURL: 'https://jsonplaceholder.typicode.com',
});
const posts = await baseFetcher('/posts')
const post = await baseFetcher('/posts/1')
baseFetcher
ã䜿ããšã
await ofetch('/posts', {
baseURL: 'https://jsonplaceholder.typicode.com'
})
ãšåãåããããŸããçæãããªããžã§ã¯ãã¯ofetch
ãšåã䜿ãæ¹ãã§ãã第2åŒæ°ã«ãªãã·ã§ã³èšå®ãæå®ããã°ãèšå®ã®è¿œå ãäžæžããã§ããŸãïŒ
ãã®æ©èœã䜿ããšå
±éã§èšå®ããããªãã·ã§ã³ãããå Žåããã¡ãã¡èšè¿°ããªããŠæžã¿ãŸããã
ãããã«
ãªããšãªãã䟿å©ãªãã ãªããšæã£ãŠããofetchã§ãããããã£ãã調ã¹ãŠã¿ããšããããªæ©èœããããã ïŒãšããçºèŠãå€ããããŸããããã®èšäºã§çŽ¹ä»ããããŠããªãæ©èœããŸã ãŸã ããã®ã§ãæ°ã«ãªã£ãæ¹ã¯ãã²ofetchã®READMEãèªãã§ã¿ãŠãã ããïŒ
ä»åãèšäºãäœæããã«ããã£ãŠãofetchã®ãœãŒã¹ã³ãŒããèªãã§ã¿ãã®ã§ããïŒäŒç€Ÿã®å 茩æ¹ãšäžç·ã«èªã¿ãŸãããããããšãããããŸããïŒïŒïŒãããã«ãã£ãŠãªãã·ã§ã³èšå®ãžã®ç解ãæ·±ãŸããŸããããã³ãŒãã®æžãæ¹ãåèã«ãªããŸããããããããæ°ã«ãªã£ãã©ã€ãã©ãªã®ãœãŒã¹ã³ãŒããèªãã§ãããããšæããŸãïŒ
èªãã§ããã ãããããšãããããŸããð
åè