[{"data":1,"prerenderedAt":957},["ShallowReactive",2],{"page-\u002Fapi\u002Fconsommer-une-api-externe":3,"pieces-api":914,"autour-\u002Fapi\u002Fconsommer-une-api-externe":939,"prerequis-\u002Fapi\u002Fconsommer-une-api-externe":944,"plan-api":946},{"id":4,"title":5,"body":6,"description":877,"extension":878,"ligne":879,"meta":880,"motsCles":881,"navigation":224,"niveau":886,"path":887,"prerequis":888,"ressources":890,"seo":902,"sources":903,"stem":912,"__hash__":913},"docs\u002Fapi\u002F03.consommer-une-api-externe.md","Consommer une API externe",{"type":7,"value":8,"toc":868},"minimark",[9,14,32,36,45,48,58,76,92,96,106,343,352,356,376,535,545,559,563,573,702,714,718,727,737,822,828,832,864],[10,11,13],"h2",{"id":12},"ce-que-tu-vas-apprendre","Ce que tu vas apprendre",[15,16,17,21,29],"ul",{},[18,19,20],"li",{},"Appeler une API publique que tu n'as pas écrite.",[18,22,23,24,28],{},"Ne garder que les champs utiles grâce à ",[25,26,27],"code",{},"transform",".",[18,30,31],{},"Relancer l'appel quand un paramètre change, et gérer l'échec.",[10,33,35],{"id":34},"une-api-qui-existe-déjà","Une API qui existe déjà",[37,38,39,40,44],"p",{},"Tu n'as pas besoin d'écrire toutes tes API. Beaucoup de services en publient. ",[41,42,43],"strong",{},"Consommer"," une API, c'est l'appeler comme client.",[37,46,47],{},"TheMealDB est une API de recettes qui répond en JSON, sans clé pour la recherche testée ici. Ouvre cette adresse dans ton navigateur :",[49,50,55],"pre",{"className":51,"code":53,"language":54},[52],"language-text","https:\u002F\u002Fwww.themealdb.com\u002Fapi\u002Fjson\u002Fv1\u002F1\u002Fsearch.php?s=Arrabiata\n","text",[25,56,53],{"__ignoreMap":57},"",[37,59,60,61,64,65,68,69,72,73,28],{},"La réponse contient une clé ",[25,62,63],{},"meals",", un tableau de repas. Chacun a notamment ",[25,66,67],{},"idMeal",", ",[25,70,71],{},"strMeal"," (le nom) et ",[25,74,75],{},"strCategory",[77,78,79],"note",{},[37,80,81,82,87,88,91],{},"Le cours ",[83,84,86],"a",{"href":85},"\u002Fnuxt\u002Frecuperer-des-donnees","Récupérer des données"," a présenté ",[25,89,90],{},"useFetch"," sur ta propre API. Ici, l'adresse change, la mécanique reste la même.",[10,93,95],{"id":94},"lappel-le-plus-simple","L'appel le plus simple",[37,97,98,99,101,102,105],{},"Passe l'adresse complète à ",[25,100,90],{},", avec les paramètres dans ",[25,103,104],{},"query"," :",[49,107,112],{"className":108,"code":109,"filename":110,"language":111,"meta":57,"style":57},"language-vue shiki shiki-themes github-light-default github-dark-default github-dark-default","\u003Cscript setup lang=\"ts\">\nconst { data, status, error } = await useFetch(\n  'https:\u002F\u002Fwww.themealdb.com\u002Fapi\u002Fjson\u002Fv1\u002F1\u002Fsearch.php',\n  { query: { s: 'Arrabiata' } }\n)\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cp v-if=\"status === 'pending'\">Chargement...\u003C\u002Fp>\n  \u003Cp v-else-if=\"error\">L'API ne répond pas.\u003C\u002Fp>\n  \u003Cul v-else>\n    \u003Cli v-for=\"m in data?.meals\" :key=\"m.idMeal\">{{ m.strMeal }}\u003C\u002Fli>\n  \u003C\u002Ful>\n\u003C\u002Ftemplate>\n","app\u002Fpages\u002Fexterne.vue","vue",[25,113,114,144,182,191,203,209,219,226,236,259,281,293,324,334],{"__ignoreMap":57},[115,116,119,123,127,131,134,137,141],"span",{"class":117,"line":118},"line",1,[115,120,122],{"class":121},"scfrF","\u003C",[115,124,126],{"class":125},"s5JFL","script",[115,128,130],{"class":129},"s5iOY"," setup",[115,132,133],{"class":129}," lang",[115,135,136],{"class":121},"=",[115,138,140],{"class":139},"shWOn","\"ts\"",[115,142,143],{"class":121},">\n",[115,145,147,151,154,157,159,162,164,167,170,172,175,179],{"class":117,"line":146},2,[115,148,150],{"class":149},"sOnC1","const",[115,152,153],{"class":121}," { ",[115,155,156],{"class":129},"data",[115,158,68],{"class":121},[115,160,161],{"class":129},"status",[115,163,68],{"class":121},[115,165,166],{"class":129},"error",[115,168,169],{"class":121}," } ",[115,171,136],{"class":149},[115,173,174],{"class":149}," await",[115,176,178],{"class":177},"syCW7"," useFetch",[115,180,181],{"class":121},"(\n",[115,183,185,188],{"class":117,"line":184},3,[115,186,187],{"class":139},"  'https:\u002F\u002Fwww.themealdb.com\u002Fapi\u002Fjson\u002Fv1\u002F1\u002Fsearch.php'",[115,189,190],{"class":121},",\n",[115,192,194,197,200],{"class":117,"line":193},4,[115,195,196],{"class":121},"  { query: { s: ",[115,198,199],{"class":139},"'Arrabiata'",[115,201,202],{"class":121}," } }\n",[115,204,206],{"class":117,"line":205},5,[115,207,208],{"class":121},")\n",[115,210,212,215,217],{"class":117,"line":211},6,[115,213,214],{"class":121},"\u003C\u002F",[115,216,126],{"class":125},[115,218,143],{"class":121},[115,220,222],{"class":117,"line":221},7,[115,223,225],{"emptyLinePlaceholder":224},true,"\n",[115,227,229,231,234],{"class":117,"line":228},8,[115,230,122],{"class":121},[115,232,233],{"class":125},"template",[115,235,143],{"class":121},[115,237,239,242,244,247,249,252,255,257],{"class":117,"line":238},9,[115,240,241],{"class":121},"  \u003C",[115,243,37],{"class":125},[115,245,246],{"class":129}," v-if",[115,248,136],{"class":121},[115,250,251],{"class":139},"\"status === 'pending'\"",[115,253,254],{"class":121},">Chargement...\u003C\u002F",[115,256,37],{"class":125},[115,258,143],{"class":121},[115,260,262,264,266,269,271,274,277,279],{"class":117,"line":261},10,[115,263,241],{"class":121},[115,265,37],{"class":125},[115,267,268],{"class":129}," v-else-if",[115,270,136],{"class":121},[115,272,273],{"class":139},"\"error\"",[115,275,276],{"class":121},">L'API ne répond pas.\u003C\u002F",[115,278,37],{"class":125},[115,280,143],{"class":121},[115,282,284,286,288,291],{"class":117,"line":283},11,[115,285,241],{"class":121},[115,287,15],{"class":125},[115,289,290],{"class":129}," v-else",[115,292,143],{"class":121},[115,294,296,299,301,304,306,309,312,314,317,320,322],{"class":117,"line":295},12,[115,297,298],{"class":121},"    \u003C",[115,300,18],{"class":125},[115,302,303],{"class":129}," v-for",[115,305,136],{"class":121},[115,307,308],{"class":139},"\"m in data?.meals\"",[115,310,311],{"class":129}," :key",[115,313,136],{"class":121},[115,315,316],{"class":139},"\"m.idMeal\"",[115,318,319],{"class":121},">{{ m.strMeal }}\u003C\u002F",[115,321,18],{"class":125},[115,323,143],{"class":121},[115,325,327,330,332],{"class":117,"line":326},13,[115,328,329],{"class":121},"  \u003C\u002F",[115,331,15],{"class":125},[115,333,143],{"class":121},[115,335,337,339,341],{"class":117,"line":336},14,[115,338,214],{"class":121},[115,340,233],{"class":125},[115,342,143],{"class":121},[37,344,345,347,348,351],{},[25,346,104],{}," fabrique la fin de l'adresse : ",[25,349,350],{},"?s=Arrabiata",". Tu n'as pas à coller les morceaux à la main, et Nuxt encode les caractères spéciaux.",[10,353,355],{"id":354},"ne-garder-que-lutile","Ne garder que l'utile",[37,357,358,359,68,362,68,365,368,369,372,373,375],{},"Cette API renvoie des dizaines de champs par repas (",[25,360,361],{},"strMealThumb",[25,363,364],{},"strInstructions",[25,366,367],{},"strIngredient1"," à ",[25,370,371],{},"strIngredient20","...). Ton site n'en veut que trois. L'option ",[25,374,27],{}," modifie la réponse avant qu'elle soit stockée :",[49,377,381],{"className":378,"code":379,"language":380,"meta":57,"style":57},"language-ts shiki shiki-themes github-light-default github-dark-default github-dark-default","type Repas = { idMeal: string, strMeal: string, strCategory: string }\n\nconst { data: recettes } = await useFetch('https:\u002F\u002Fwww.themealdb.com\u002Fapi\u002Fjson\u002Fv1\u002F1\u002Fsearch.php', {\n  query: { s: 'Arrabiata' },\n  transform: (reponse: { meals: Repas[] | null }) =>\n    (reponse.meals ?? []).map(m => ({ id: m.idMeal, titre: m.strMeal, categorie: m.strCategory }))\n})\n","ts",[25,382,383,424,428,459,469,505,530],{"__ignoreMap":57},[115,384,385,388,392,395,397,399,402,405,407,409,411,413,415,417,419,421],{"class":117,"line":118},[115,386,387],{"class":149},"type",[115,389,391],{"class":390},"sIXEE"," Repas",[115,393,394],{"class":149}," =",[115,396,153],{"class":121},[115,398,67],{"class":390},[115,400,401],{"class":149},":",[115,403,404],{"class":129}," string",[115,406,68],{"class":121},[115,408,71],{"class":390},[115,410,401],{"class":149},[115,412,404],{"class":129},[115,414,68],{"class":121},[115,416,75],{"class":390},[115,418,401],{"class":149},[115,420,404],{"class":129},[115,422,423],{"class":121}," }\n",[115,425,426],{"class":117,"line":146},[115,427,225],{"emptyLinePlaceholder":224},[115,429,430,432,434,436,439,442,444,446,448,450,453,456],{"class":117,"line":184},[115,431,150],{"class":149},[115,433,153],{"class":121},[115,435,156],{"class":390},[115,437,438],{"class":121},": ",[115,440,441],{"class":129},"recettes",[115,443,169],{"class":121},[115,445,136],{"class":149},[115,447,174],{"class":149},[115,449,178],{"class":177},[115,451,452],{"class":121},"(",[115,454,455],{"class":139},"'https:\u002F\u002Fwww.themealdb.com\u002Fapi\u002Fjson\u002Fv1\u002F1\u002Fsearch.php'",[115,457,458],{"class":121},", {\n",[115,460,461,464,466],{"class":117,"line":193},[115,462,463],{"class":121},"  query: { s: ",[115,465,199],{"class":139},[115,467,468],{"class":121}," },\n",[115,470,471,474,477,480,482,484,486,488,490,493,496,499,502],{"class":117,"line":205},[115,472,473],{"class":177},"  transform",[115,475,476],{"class":121},": (",[115,478,479],{"class":390},"reponse",[115,481,401],{"class":149},[115,483,153],{"class":121},[115,485,63],{"class":390},[115,487,401],{"class":149},[115,489,391],{"class":390},[115,491,492],{"class":121},"[] ",[115,494,495],{"class":149},"|",[115,497,498],{"class":129}," null",[115,500,501],{"class":121}," }) ",[115,503,504],{"class":149},"=>\n",[115,506,507,510,513,516,519,521,524,527],{"class":117,"line":211},[115,508,509],{"class":121},"    (reponse.meals ",[115,511,512],{"class":149},"??",[115,514,515],{"class":121}," []).",[115,517,518],{"class":177},"map",[115,520,452],{"class":121},[115,522,523],{"class":390},"m",[115,525,526],{"class":149}," =>",[115,528,529],{"class":121}," ({ id: m.idMeal, titre: m.strMeal, categorie: m.strCategory }))\n",[115,531,532],{"class":117,"line":221},[115,533,534],{"class":121},"})\n",[37,536,537,538,541,542,544],{},"Deux avantages. Tes composants lisent ",[25,539,540],{},"recette.titre",", pas ",[25,543,71],{}," : si l'API change, tu corriges un seul endroit. Et moins de données sont envoyées du serveur au navigateur.",[546,547,548],"tip",{},[37,549,550,551,554,555,558],{},"Cette API renvoie ",[25,552,553],{},"meals: null"," quand rien ne correspond. Le ",[25,556,557],{},"?? []"," évite une erreur dans ce cas. Lis toujours la documentation d'une API pour connaître ses réponses « vides ».",[10,560,562],{"id":561},"relancer-quand-un-paramètre-change","Relancer quand un paramètre change",[37,564,565,566,569,570,572],{},"Pour une recherche, le texte tapé change. Mets-le dans un ",[25,567,568],{},"ref"," et dis à ",[25,571,90],{}," de surveiller :",[49,574,577],{"className":108,"code":575,"filename":576,"language":111,"meta":57,"style":57},"\u003Cscript setup lang=\"ts\">\nconst terme = ref('Arrabiata')\n\nconst { data } = await useFetch('https:\u002F\u002Fwww.themealdb.com\u002Fapi\u002Fjson\u002Fv1\u002F1\u002Fsearch.php', {\n  query: { s: terme }\n})\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cinput v-model=\"terme\" placeholder=\"Rechercher une recette\" \u002F>\n\u003C\u002Ftemplate>\n","app\u002Fpages\u002Frecherche.vue",[25,578,579,595,613,617,639,644,648,656,660,668,694],{"__ignoreMap":57},[115,580,581,583,585,587,589,591,593],{"class":117,"line":118},[115,582,122],{"class":121},[115,584,126],{"class":125},[115,586,130],{"class":129},[115,588,133],{"class":129},[115,590,136],{"class":121},[115,592,140],{"class":139},[115,594,143],{"class":121},[115,596,597,599,602,604,607,609,611],{"class":117,"line":146},[115,598,150],{"class":149},[115,600,601],{"class":129}," terme",[115,603,394],{"class":149},[115,605,606],{"class":177}," ref",[115,608,452],{"class":121},[115,610,199],{"class":139},[115,612,208],{"class":121},[115,614,615],{"class":117,"line":184},[115,616,225],{"emptyLinePlaceholder":224},[115,618,619,621,623,625,627,629,631,633,635,637],{"class":117,"line":193},[115,620,150],{"class":149},[115,622,153],{"class":121},[115,624,156],{"class":129},[115,626,169],{"class":121},[115,628,136],{"class":149},[115,630,174],{"class":149},[115,632,178],{"class":177},[115,634,452],{"class":121},[115,636,455],{"class":139},[115,638,458],{"class":121},[115,640,641],{"class":117,"line":205},[115,642,643],{"class":121},"  query: { s: terme }\n",[115,645,646],{"class":117,"line":211},[115,647,534],{"class":121},[115,649,650,652,654],{"class":117,"line":221},[115,651,214],{"class":121},[115,653,126],{"class":125},[115,655,143],{"class":121},[115,657,658],{"class":117,"line":228},[115,659,225],{"emptyLinePlaceholder":224},[115,661,662,664,666],{"class":117,"line":238},[115,663,122],{"class":121},[115,665,233],{"class":125},[115,667,143],{"class":121},[115,669,670,672,675,678,680,683,686,688,691],{"class":117,"line":261},[115,671,241],{"class":121},[115,673,674],{"class":125},"input",[115,676,677],{"class":129}," v-model",[115,679,136],{"class":121},[115,681,682],{"class":139},"\"terme\"",[115,684,685],{"class":129}," placeholder",[115,687,136],{"class":121},[115,689,690],{"class":139},"\"Rechercher une recette\"",[115,692,693],{"class":121}," \u002F>\n",[115,695,696,698,700],{"class":117,"line":283},[115,697,214],{"class":121},[115,699,233],{"class":125},[115,701,143],{"class":121},[37,703,704,705,707,708,710,711,713],{},"Passer le ",[25,706,568],{}," dans ",[25,709,104],{}," suffit : ",[25,712,90],{}," relance la requête à chaque modification. C'est le même principe que la fonction passée en adresse, vue dans le cours Nuxt.",[10,715,717],{"id":716},"quand-lapi-échoue","Quand l'API échoue",[37,719,720,721,723,724,726],{},"Une API externe n'est pas sous ton contrôle. Elle peut être lente, tomber, ou changer de format. Prévois toujours trois états : chargement, erreur, résultat vide. Dans le code plus haut, ",[25,722,161],{}," et ",[25,725,166],{}," les couvrent.",[37,728,729,730,733,734,105],{},"Pour une action déclenchée par un clic, utilise ",[25,731,732],{},"$fetch"," avec un ",[25,735,736],{},"try\u002Fcatch",[49,738,740],{"className":378,"code":739,"language":380,"meta":57,"style":57},"async function rechercher() {\n  try {\n    resultat.value = await $fetch('https:\u002F\u002Fwww.themealdb.com\u002Fapi\u002Fjson\u002Fv1\u002F1\u002Fsearch.php', {\n      query: { s: terme.value }\n    })\n  } catch {\n    message.value = 'Recherche impossible pour le moment.'\n  }\n}\n",[25,741,742,756,764,782,787,792,802,812,817],{"__ignoreMap":57},[115,743,744,747,750,753],{"class":117,"line":118},[115,745,746],{"class":149},"async",[115,748,749],{"class":149}," function",[115,751,752],{"class":177}," rechercher",[115,754,755],{"class":121},"() {\n",[115,757,758,761],{"class":117,"line":146},[115,759,760],{"class":149},"  try",[115,762,763],{"class":121}," {\n",[115,765,766,769,771,773,776,778,780],{"class":117,"line":184},[115,767,768],{"class":121},"    resultat.value ",[115,770,136],{"class":149},[115,772,174],{"class":149},[115,774,775],{"class":177}," $fetch",[115,777,452],{"class":121},[115,779,455],{"class":139},[115,781,458],{"class":121},[115,783,784],{"class":117,"line":193},[115,785,786],{"class":121},"      query: { s: terme.value }\n",[115,788,789],{"class":117,"line":205},[115,790,791],{"class":121},"    })\n",[115,793,794,797,800],{"class":117,"line":211},[115,795,796],{"class":121},"  } ",[115,798,799],{"class":149},"catch",[115,801,763],{"class":121},[115,803,804,807,809],{"class":117,"line":221},[115,805,806],{"class":121},"    message.value ",[115,808,136],{"class":149},[115,810,811],{"class":139}," 'Recherche impossible pour le moment.'\n",[115,813,814],{"class":117,"line":228},[115,815,816],{"class":121},"  }\n",[115,818,819],{"class":117,"line":238},[115,820,821],{"class":121},"}\n",[823,824,825],"warning",{},[37,826,827],{},"Certaines API demandent une clé. Elle ne doit jamais apparaître dans du code exécuté par le navigateur. Le chapitre suivant explique comment la cacher.",[10,829,831],{"id":830},"à-retenir","À retenir",[15,833,834,843,853,858,861],{},[18,835,836,837,839,840,842],{},"Consommer une API, c'est l'appeler comme client avec ",[25,838,90],{}," (page) ou ",[25,841,732],{}," (clic).",[18,844,845,847,848,707,850,852],{},[25,846,104],{}," construit les paramètres d'adresse ; un ",[25,849,568],{},[25,851,104],{}," relance l'appel quand il change.",[18,854,855,857],{},[25,856,27],{}," ne garde que les champs utiles et isole ton site du format de l'API.",[18,859,860],{},"Prévois le chargement, l'erreur et le résultat vide : une API externe peut échouer.",[18,862,863],{},"Une clé d'API ne se met jamais dans le code du navigateur.",[865,866,867],"style",{},"html pre.shiki code .scfrF, html code.shiki .scfrF{--shiki-light:#1F2328;--shiki-default:#E6EDF3;--shiki-dark:#E6EDF3}html pre.shiki code .s5JFL, html code.shiki .s5JFL{--shiki-light:#116329;--shiki-default:#7EE787;--shiki-dark:#7EE787}html pre.shiki code .s5iOY, html code.shiki .s5iOY{--shiki-light:#0550AE;--shiki-default:#79C0FF;--shiki-dark:#79C0FF}html pre.shiki code .shWOn, html code.shiki .shWOn{--shiki-light:#0A3069;--shiki-default:#A5D6FF;--shiki-dark:#A5D6FF}html pre.shiki code .sOnC1, html code.shiki .sOnC1{--shiki-light:#CF222E;--shiki-default:#FF7B72;--shiki-dark:#FF7B72}html pre.shiki code .syCW7, html code.shiki .syCW7{--shiki-light:#8250DF;--shiki-default:#D2A8FF;--shiki-dark:#D2A8FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sIXEE, html code.shiki .sIXEE{--shiki-light:#953800;--shiki-default:#FFA657;--shiki-dark:#FFA657}",{"title":57,"searchDepth":146,"depth":184,"links":869},[870,871,872,873,874,875,876],{"id":12,"depth":146,"text":13},{"id":34,"depth":146,"text":35},{"id":94,"depth":146,"text":95},{"id":354,"depth":146,"text":355},{"id":561,"depth":146,"text":562},{"id":716,"depth":146,"text":717},{"id":830,"depth":146,"text":831},"Appeler une API publique depuis Nuxt, transformer sa réponse pour ne garder que l'utile et gérer les erreurs et les paramètres.","md","api",{},[882,90,27,104,883,166,884,885,732],"API externe","watch","TheMealDB","typage","debutant","\u002Fapi\u002Fconsommer-une-api-externe",[889],"\u002Fapi\u002Fmethodes-et-codes-de-statut",[891,895,899],{"nom":892,"url":893,"type":894,"anglais":224},"Documentation officielle de Nuxt, récupération des données","https:\u002F\u002Fnuxt.com\u002Fdocs\u002F4.x\u002Fgetting-started\u002Fdata-fetching","doc",{"nom":896,"url":897,"type":898},"Utiliser l'API Fetch sur MDN","https:\u002F\u002Fdeveloper.mozilla.org\u002Ffr\u002Fdocs\u002FWeb\u002FAPI\u002FFetch_API\u002FUsing_Fetch","cours",{"nom":900,"url":901,"type":898},"Manipuler des données JSON sur MDN","https:\u002F\u002Fdeveloper.mozilla.org\u002Ffr\u002Fdocs\u002FLearn_web_development\u002FCore\u002FScripting\u002FJSON",{"title":5,"description":877},[904,906,909],{"nom":905,"url":893},"Récupération des données (en anglais)",{"nom":907,"url":908},"useFetch (en anglais)","https:\u002F\u002Fnuxt.com\u002Fdocs\u002F4.x\u002Fapi\u002Fcomposables\u002Fuse-fetch",{"nom":910,"url":911},"$fetch (en anglais)","https:\u002F\u002Fnuxt.com\u002Fdocs\u002F4.x\u002Fapi\u002Futils\u002Fdollarfetch","api\u002F03.consommer-une-api-externe","5_l76sqs0g_LyUXKZyklKOnTIk2xxCb6ToXdAOfSkr4",[915,919,922,923,927,931,935],{"path":916,"title":917,"stem":918},"\u002Fapi\u002Fcomprendre-les-api","Comprendre les API","api\u002F01.comprendre-les-api",{"path":889,"title":920,"stem":921},"Méthodes et codes de statut","api\u002F02.methodes-et-codes-de-statut",{"path":887,"title":5,"stem":912},{"path":924,"title":925,"stem":926},"\u002Fapi\u002Fcacher-une-cle-d-api","Cacher une clé d'API","api\u002F04.cacher-une-cle-d-api",{"path":928,"title":929,"stem":930},"\u002Fapi\u002Fecrire-une-api-complete","Écrire une API complète","api\u002F05.ecrire-une-api-complete",{"path":932,"title":933,"stem":934},"\u002Fapi\u002Fsecurite-et-limites","Sécurité et limites","api\u002F06.securite-et-limites",{"path":936,"title":937,"stem":938},"\u002Fapi","API","api\u002Findex",[940,942],{"title":920,"path":889,"stem":921,"description":941,"children":-1},"Choisir la bonne méthode HTTP (GET, POST, PUT, PATCH, DELETE) et lire les codes de réponse pour savoir ce qui s'est passé.",{"title":925,"path":924,"stem":926,"description":943,"children":-1},"Pourquoi une clé d'API ne doit jamais atteindre le navigateur, et comment la garder côté serveur avec runtimeConfig et une route intermédiaire.",[945],{"path":889,"title":920,"ligne":879},[947,948,949,950,952,953,955],{"path":916,"title":917,"niveau":886,"stem":918},{"path":889,"title":920,"niveau":886,"stem":921},{"path":887,"title":5,"niveau":886,"stem":912},{"path":924,"title":925,"niveau":951,"stem":926},"intermediaire",{"path":928,"title":929,"niveau":951,"stem":930},{"path":932,"title":933,"niveau":954,"stem":934},"avance",{"path":936,"title":937,"niveau":956,"stem":938},"memo",1794583449773]