Fórum nápovědy

Seznam

Jak se spojit s REST API

Jan Horinek

17.5.2024 v 10:17

Omlouvám se za ryze začátečnický dotaz. Nikdy jsem s API nepracoval a odpověď jsem nenašel ani v "Co je REST API Mapy.cz", ani ve FAQ.
Mám vytvořený projekt, chápu systém plateb a mám vytvořený klíč.

Předpokládám, že klíč bude v konstantě API_KEY na začátku JavaScriptu.

A teď to, čemu nerozumím:
1. Klíč je viditelný pro veřejnost ve výpisu kódu. Je to tak, že si ho musím zabezpečit aby ho nezačal používat někdo jiný?
2. Jak se spojím s novým API? V předchozím API byl v hlavičce stránky odkaz na loader. js. Předpokládám, že tím se načte JS soubor s balíkem funkcí, které pak lze volat a ty se provedou přes API.

Jak se ze souboru umístěném na mém PC spojím s novým API? To jsem ve FAQ nenašel.

Pokud jsem výše uvedl nějaký šokující nesmysl, omlouvám se, teprve do toho pronikám.
Ve svém projektu nebudu vykreslovat mapy, pouze budu načítat výšková data a vykteslovat přes JS výškový profil do vlastníhoi grafu.

Jan Kuchař

17.5.2024 v 10:56

Dobrý den,
proti zneužití je potřeba API klič zabezpečit
Obvykle se to řeší tak že si vytvoříte dva API klíče (je možno jakékoliv množství klíčů v rámci jednoho projektu) a jeden který budete mít na webu zabezpečíte pro konkrétní URL
Druhý nezabezpečený budete používat lokálně na PC při programování a testování
API klíč se zadává při volání každé funkce REST API i při načítání mapových dlaždic
na konkrétní kod se můžete podívat v ukázkách k jednotlivým funkcím
https://developer.mapy.cz/rest-api/funkce/
Jednotlivé funkce lze volat i bez zobrazení mapy
co se týká vámi vámi zmiňovaných výškových dat je při volání nutné dodržet omezení a to max 256 souřadnic pro jeden dotaz a max rozsah souřadnic 1x1 stupeň

Jan Horinek

17.5.2024 v 11:25

Díky, jak tedy JavaScript pozná, že volám API na mapy.cz?

Jan Kuchař reagoval na příspěvek od Jan Horinek

17.5.2024 v 11:35

pozná to z URL přes kterou je funkce volána

https://api.mapy.cz/v1/elevation?lang=cs&positions=${lon}%2C${lat}&apikey=${API_KEY}

Jan Horinek

17.5.2024 v 11:40

Aha, jasně, díky. Ten loader.js, který jsem zmiňoval prve právě zajišťoval přidání URL mapy.cz. Teď to dává smysl.

https://technologyadvice.com/blog/information-technology/how-to-use-an-api/

Jan Buriánek

17.5.2024 v 12:57

A já vám k tomu ještě poradím, jak správně vložit řadu až 256ti souřadnic do poptávky, protože tam to musí být správně vložené, jednotlivé souřadnice oddělené středníkem a mezi LAT LON hodnotou čárka, tečka je desetinná tečka.

např. takto:
let sou=""; for(let a of body){sou+=sou==""?"":";"; sou+=a.lng+","+a.lat}

tento kód má na začátku smyčky v proměnné sou prázdné uvozovky, takže nic nepřiřadí a vloží první LON - LAT souřadnice (pozor na pořadí LON-LAT!), a pro každý další bod přidá před něj středník. Tím se zajistí, že není středník na konci řetězce souřadnic. (sou je zkratka souřadnice... :)

no a pak to poptáte třeba takto
fetch('https://api.mapy.cz/v1/elevation?positions='+sou+'&apikey='+"API_KEY")
.then( .... atd

Jan Horinek

17.5.2024 v 15:33

Bezva, díky moc, už to funguje.

Jan Horinek

23.5.2024 v 22:03

Ještě dotaz.

Mám funkci

function ZavolejAPI(souradnice, pocet)
{

let apiUrl = 'https://api.mapy.cz/v1/elevation?lang=cs&positions=' + souradnice + '&apikey=' + API_KEY;

let vysky = [];
let vyska = 0;

fetch(apiUrl)

.then(response => response.json())

.then(data => {

for(let i = 0; i < pocet; i++)
{
vysky.push(data.items[i].elevation);
}

})

.catch(error => console.error('Chyba při volání API: ', error));

}


a volám jí

nadm_vyska_paty = ZavolejAPI(lng_end + ',' + lat_end, 1);

Kam do funkce mám umístit return aby vrátil hodnotu vyska = data.items[0].elevation ?
Neboli jedinou hodnotu pole data.items.

Jan Buriánek reagoval na příspěvek od Jan Horinek

23.5.2024 v 22:55

To je otázka, jak dalece si rozumíte s asynchronními funkcemi.
Funkce ZavolejAPI() proběhne celá, ale odloží všechny kódy za oběma .then na pozdější asynchronní zpracování, a nemůže vrátit žádný výsledek, protože ho ještě nezná, jen ho poptá.
Váš program pokračuje tam, odkud jste ZavolejAPI() zavolal. Ale žádné return nemůže vrátit hodnotu.

Na základě poptávky fetch() prohlížeč asynchronně (tedy bez toho, aby na to měl váš script nějaký vliv) pošle požadavek na server a bude čekat na jeho vrácení. Jakmile server pošle zpět hodnoty, sama se spustí funkce za prvním .then, tedy .json zpracování návratu, to je taky asynchronní. Jakmile je to dokončeno, sama se spustí funkce za dalším .then, tedy .then(data ... ) a ta se celá provede.
Ve smyčce tam máte uložení návratových hodnot z data do vaší proměnné vysky[].

Problém je v tom, že tuto proměnnou definujete let uvnitř funkce ZavolejAPI(), no a tím pádem proměnná existuje pouze uvnitř této funkce.
Čili i když se to spustilo samo dodatečně asynchronně, tak tu proměnnou to zná a data má kam uložit, nebude to vracet chybu.
Jenže jakmile to dokončí, proměnná i s hodnotami se definitivně ztratí.
Dalším voláním funkce ZavolejAPI() se to opakuje, proměnná let vysky=[] se definuje znovu, opět jen uvnitř funkce ZavolejAPI().
Stejně se zde ale bude chovat i var vysky=[]

Musíte buď nepoužít let nebo var, jen vysky=[], pak bude proměnná globální a hodnoty v ní zůstanou.
A dalším voláním se přepíšou na nové (samozřejmě až po asynchronním návratu)
Lepší je ale definovat proměnnou mimo funkci, před funkcí
Hodnoty se pak budou do proměnné výšky jen stále přidávat.
To samé platí i pro let vyska.

V následující ukázce (úpravě vašeho kódu) ani nepoužiju let vyska=0, ale po návratu dat se sama spustí funkce vykonejNeco(), jíž jako parametr předáme tu jednu první výšku.

let vysky = [];
//let vyska = 0;

function ZavolejAPI(souradnice, pocet){
let apiUrl = 'https://api.mapy.cz/v1/elevation?lang=cs&positions=' + souradnice + '&apikey=' + API_KEY;
fetch(apiUrl)
.then(response => response.json())
.then(data => {
for(let i = 0; i < pocet; i++){vysky.push(data.items[i].elevation);}

// vyska=data.items[0].elevation

vykonejNeco(data.items[0].elevation)

})
.catch(error => console.error('Chyba při volání API: ', error));
}

function vykonejNeco(vyska){console.log(vyska)}


(psal jsem to od ruky z paměti zde přímo v okně fóra, můžou tam být chyby)

Jan Buriánek

23.5.2024 v 23:12

Ještě doplním, že pokud byste chtěl, aby nadřazená funkce se zastavila a počkala na vrácení hodnoty, pak musí být nadřazená funkce asynchronní, v ní definovaná proměnná, do níž se uloží promise požadavek a na ten se pomocí await počká. Návrat pak v promise obsahuje i vrácené hodnoty, čili je to podobné return, jen se na to musí počkat.
...není to úplně jednoduché

Zkuste si prostudovat poslední funkci: async function main() {...} v ukázce čtení elevace zde:
https://developer.mapy.cz/rest-api/tutorialy/zobrazeni-vyskoveho-profilu-trasy/
Tam je to použito.

Jan Horinek

24.5.2024 v 11:29

Bezva, moc Vám děkuji za trpělivost a excelentní vysvětlení!

Jan Buriánek reagoval na příspěvek od Jan Horinek

24.5.2024 v 11:34

👍

Jan Horinek

24.5.2024 v 14:35

Ještě bych si dovolil Vás potrápit. Sestavil jsem to takto


let nadm_vyska_paty = 0;

nadm_vyska_paty = getElevation(lng_end + ',' + lat_end)

async function getElevation(souradnice)
{

const apiUrl = 'https://api.mapy.cz/v1/elevation?lang=cs&positions=' + souradnice + '&apikey=' + API_KEY;
const response = await fetch(apiUrl);
const data = await response.json();

return data.items[0].elevation;

}

Do proměnné nadm_vyska_paty se však neukládá hodnota, ale Promise, který má state a value.
Je nějaká metoda, jak do globální proměnné uložit value z Promise tak, aby to tam zůstalo a dalo se s tou proměnnou pracovat běžným způsobem?

Jan Kuchař reagoval na příspěvek od Jan Horinek

24.5.2024 v 15:07

Dobrý den,
funkce se zdá být už OK (podobně to mám také)
ale funkci bych volal takto:

getElevation(lng_end + ',' + lat_end).then( function(value) {
nadm_vyska_paty=value
// a zde další váš kod třeba
alert(nadm_vyska_paty)
})

protože pracovat s navrácenou hodnotou můžete teprve až jí vrátí

Jan Horinek

24.5.2024 v 15:27

Dík, možná, že chci něco neuskutečnitelného, ale

let nadm_vyska_paty=0;

getElevation(lng_end + ',' + lat_end).then( function(value) {
nadm_vyska_paty=value
console.log(nadm_vyska_paty);
})

console.log(nadm_vyska_paty);

vrátí v konzoli
0
470

protože to volání mimo metodu .then() se provede jako první a kód mimo ni bude brát nadm_vyska_paty jako 0, protože se provede celý jako první.
Lze tu načtenou hodnotu nějak vyvést ven mimo .then()?
Já jsem se právě domníval, že await udělá přesně tohle ...

Jan Horinek

24.5.2024 v 17:02

Už to chápu, tomu volání pokaždé když potřebuji hodnotu se nevyhnu. Nevadí, dík za pomoc.

Jan Kuchař reagoval na příspěvek od Jan Horinek

24.5.2024 v 18:40

No volat ji pokaždé nemusíte pokud proměnou nadm_vyska_paty vytvoříte mimo funkci jako globální (jak už psal Honza Buriánek)
pak potom co do ní bude v then() uložená hodnota k ní můžete přistupovat znovu i z jiných funkcí
když to vezmu zjednodušeně a volal bych to takto

let nadm_vyska_paty=0;

getElevation(lng_end + ',' + lat_end).then( function(value) {
nadm_vyska_paty=value
console.log(nadm_vyska_paty);
})
alert("XXX")
console.log(nadm_vyska_paty);

vrátí v konzoli
470
470

ptotože ten alert() pozastaví kod a než ho zavřete tak then() už má má vrácenou hodnotu a je uložena v nadm_vyska_paty

Jan Horinek

24.5.2024 v 19:05

Takže ten Alert je jediné řešení jak pozastavit kód? Ten se mi tam moc nehodí.

Jan Kuchař reagoval na příspěvek od Jan Horinek

24.5.2024 v 20:24

Ne jsou i jiné možnosti to bylo jen pro rychlou ukázku že se skutečně do té promene ta hodnota uloží a je k použití i mimo funkci. Už ale nejsem u PC tak jedině až zitra

Jan Horinek

24.5.2024 v 21:25

To vnější volání za Alertem mi vrací 0 (úvodní deklarace globální proměnné je 'let nadm_vyska_paty = 0').
To vnitřní vrací 470.

Jan Buriánek

24.5.2024 v 23:26

Jsem na vikend mimo, taky nejsem u PC. Co to tu ale ctu na mobilu, tak ano, promena ma po deklaraci 0, a po chvili se "sama" zmeni na 470. To tak je, to je chovani async funkci. Jakmile se do globalni promene hodmota ulozi navratem, tak uz tam zustane i pro dalsi pouziti. Dokud ji nekde neprepisete.
Proste pouzit ji.muzete az po navratu. A navrat vznika sam. Klidne i vic jak jednu vterinu po poptavce, zalezi na rychlosti internetu a vytizenosti serveru. Vas kod uz je davno vykonan, to trva milisekundy. Tomu musite kod uzpusobit. Lze treba deklarovat promenou jako = -1 a pak porovnavat, zda uz je plusova. Dokud ne, tak nebylo vraceno.
Ale realne se to programuje tak, ze tteba vykresleni se provede samo, spustene samo navratem, protoze hodnota uz je znama.

Nový dotaz

Přiložené přílohy

    Zbývá 12MB (z 12MB)

    Jak se spojit s REST API

    Přiložené přílohy

      Zbývá 12MB (z 12MB)