Az előző cikkben, amiben az API kulcs backend-en történő elrejtéséről írtam, ígértem, hogy kifejtem majd részletesebben is az API proxy működését, ami nem teljesen transzparens proxy, mert a küldött adatokat is átalakítja, illetve a fő proxyra küldött API kulcsot is elrejti a végfelhasználó elől.
Most, hogy egy kódszínezőt is beépítettem a bogba, így minden készen áll arra, hogy kicsit részletesebben is bemutathassam az API proxy működését.
Nemrégiben készítettem egy API proxyt, ami a WeatherAPI.com-ról kéri le Budapest időjárását, a kapott JSON adatokat átdolgozza, más kulcsok alá, majd szintén JSON-t ad vissza a válaszában.
A proxy API-t Node.JS alapokon készítettem el, Express.JS használata nélkül. Az elkészült kódok megtalálhatók a Githubon és a CodeSandboxon is.
A kód a http csomagot használja a HTTP szerver létrehozására.
A http szervernek a proxy nevű függvény van átadva, ami felelős a hozzáférés header-ben történő beállításáért, illetve meghatározza a content type-ot, ami JSON lesz, mivel nekünk JSON kimenetre lesz szükségünk. A végén pedig betölti a View függvényt, aminek a response átadásra kerül. (A View függvényről kicsit később).
//Server.js file
async function proxy(req, res) {
res.setHeader("Access-Control-Allow-Origin", allowedHost);
res.setHeader("Content-Type", "application/json");
View(res);
}
Ahhoz, hogy a Weatherapi.com adataihoz hozzáférjünk, meg kell adni az WeatherAPI elérési útját és egy API kulcsot plusz a város nevét, aminek az időjárását szeretnénk lekérdezni. Ezt az egészet az API_ENDPOINT konstansba raktam. Tehát API_ENDPOINT = API url + API kulcs + városnév. Az API_KEY-t környezeti változóba mentettem el.
A Node.JS-ben a process.ent.KÖRNYEZETIVÁLTOZÓNEVE sorral lehet lekérni a futó Node.JS által tárolt környezeti változókat. Ezek akár lehetnek string-ek is, így ez tökéletesen alkalmas API kulcsok, Server JWT token kulcsok tárolására. Így az API_KEY-t process.env.API_KEY -el lehet megkapni.
Ahhoz, hogy Node.JS-ből HTTP requesteket tudjunk indítani más API-ok felé, le kell tölteni egy pack-ot az NPM-ről "node-fetch" néven, de akár jó erre az Axios is. A Node 18 esetén pedig már ezekre sem lesz szükség, mivel gyárilag támogartja.
Én a node-fetch-t választottam a WeatherAPI elérésére a proxy API-ban.. Ha ez telepítésre került, akkor a frontendoldali fetch-hez hasonló módon használható. Így ezzel a szokásos módon készítettem el a getWeather függvényt.
//Server.js file
async function getWeather() {
const response = await fetch(API_ENDPOINT);
const data = response.json();
return data;
}
Ezt a View függvény használja az adatok megjelenítésére. Az await getWeather(); értéke kerül bele egy konstansba és ez kerül kiírásra, abban az esetben, ha adatokat kérnek le a proxy-tól.
//Server.js file
res.write(
JSON.stringify({
error: false,
cityname: data.location.name,
temperature: {
celsius: data.current.temp_c,
updatetime: data.current.last_updated
},
weathericon: data.current.condition.icon,
currenttime: data.location.localtime
})
);
A WeatherAPI.com-tól érkező adatok itt kerülnek módosításra. Például az aktuális hőmérsékleti adat a data.current.temp_c néven érkezik be és a proxy ezt alakítja át temperature.celsius -ra. Így a kimeneten kb ehhez hasonló JSON fog randelkezésreállni:
{"error":false,"cityname":"Budapest","temperature":{"celsius":29,"updatetime":"2022-06-03 19:30"},"weathericon":"//cdn.weatherapi.com/weather/64x64/day/113.png","currenttime":"2022-06-03 19:40"}
Ezt az adatot pedig egy frontend fetchel az alábbi formában lehet lekérdezni:
//frontend js file
const APP_CONTAINER = document.querySelector("#app-weather");
const APP_CONTAINER = document.querySelector("#app-weather");
const WEATHER_PROXY_ENDPOINT = "https://pmuilu.sse.codesandbox.io/";
async function getWeather() {
const response = await fetch(WEATHER_PROXY_ENDPOINT);
const data = response.json();
return data;
}
function Template({ cityname, temperature, weathericon, currenttime }){
return `<div style="text-align: center;" class="widget-container"><p>${cityname}</p><img src="https://jscript.blog.hu/admin/post/edit/${weathericon}" /><p>${temperature.celsius} CELSIUS</p><p>Last update: ${temperature.updatetime}</p><p>Local date/time: ${currenttime}</p></div> `;}
function ErrorTemplate() { setInterval(()=>window.location.href = window.location.href, 10000); return ` The Backend server unavailable TRY AGAIN LATER...<a href="https://jscript.blog.hu/admin/post/edit/${WEATHER_PROXY_ENDPOINT}" target="_blank" rel="noopener noreferrer">OPEN SERVER</a> `;}
async function init() {
try {
const data = await getWeather();
console.log(data);
APP_CONTAINER.innerHTML = Template(data);
} catch (e) {
console.error("Server error");
console.error(e);
APP_CONTAINER.innerHTML = ErrorTemplate();
}
}
init();
Itt próbálhatod ki a végeredményt.
See the Pen Weather - WEATHERAPI.COM PROXY by Bzozoo (@bzozoo) on CodePen.