Node.js Cron Job – automatsko izvršavanje zakazanih zadataka

Do sada sam objavio nekoliko članaka korištenju NodeJS API-ja i svaki od njih ima istu poveznicu, a to je činjenica da se izvršavaju isključivo kada ih pozovem. U većini slučajeva to tako treba biti, ali postoje i slučajevi u kojima želim da se određeni zadatak izvrši bez da ga ručno moram pokrenuti pozivajući neki API endpoint. U tome će mi pomoći Cron Job.

Postavljanje projekta

Kreiram mapu naziva ExpressNodeCron i unutar nje pokrećem naredbu:

Odmah nakon toga instaliram Express.js i Node Cron pakete:

Sada u mapi projekta mogu vidjeti datoteku package.json koja je osnova ovog projekta.

Kreiranje API-ja

Unutar datoteke index.js koju sam upravo kreirao kopiram sljedeći sadržaj:

API odmah testiram na putanji http://localhost:8080/api/

ExpressJS API

Cron Job funkcionalnost

Sada pratim dostupnu dokumentaciju na adresi https://www.npmjs.com/package/node-cron

Na sljedećem primjeru nalazi se osnova cron job funkcionalnosti.

Na liniji 1 nalazi se "* * * * *" što označava odabrani interval u kojemu će se određeni zadatak izvršiti.

Na liniji 2 nalazi se zadatak koji će se izvršiti u zadanom intervalu.

Node.js Cron Job – automatsko izvršavanje zakazanih zadataka

Osim ranije spomenutog intervala moguće su i sljedeće kombinacije:

– više vrijednosti odvojenih zarezom

– korištenje raspona vrijednosti

– izvršavanje u koracima

– korištenje naziva mjeseca i dana umjesto brojeva (moraju biti na engleskom jeziku)

Svi ranije navedeni zadaci pokreću se prilikom startanja NodeJS servera, ali postoje još i dodatne metode pomoću kojih je moguće u određenom trenutku pokrenuti neki Cron Job, stopirati ga ili skroz ugasiti.

Start task.start();

Stop task.stop();

Jednom stopirati zadatak moguće je ponovno pokrenuti.

Primjer:

Pozivanjem putanje http://localhost:8080/api/stopiraj zaustavljam Cron Job.

Destroy task.destroy();

Jednom prekinuti zadatak nije moguće ponovno pokrenuti.

ExpressJS middleware za ograničavanje ponovljenih zahtjeva na API-je

Jedna od najvažnijih komponenti svakog API-ja, osim mogućnosti upravljanja podacima, je sigurnost. A jedna od osnovnih komponenti te sigurnosti je mogućnost blokiranja prekomjernih upita koji se šalju na pojedini API endpoint.

U ovom ću slučaju za tu svrhu koristiti Express Rate Limit modul.

Postavljanje projekta

Kreiram mapu naziva ExpressRateLimit i unutar nje pokrećem naredbu:

Odmah nakon toga instaliram Express.js i Express Rate Limit pakete:

Sada u mapi projekta mogu vidjeti datoteku package.json koja je osnova ovog projekta.

Sada imam sve potrebno za kreiranje API-ja.

Kreiranje API-ja

Kreiram index.js datoteku unutar koje kopiram sljedeći sadržaj:

API mogu testirati na putanji http://localhost:8080/api/

ExpressJS Rate Limit – zaštita API-ja

Sada, nakon što sam se uvjerio da API ispravno radi, mogu implementirati Express Rate Limit modul.

Express Rate Limit modul

Kreiram dvije krajnje točke (endpoint):

Njima pristupam putem URL-ova:

http://localhost:8080/api/putanja1 i http://localhost:8080/api/putanja2

ExpressJS Rate Limit – zaštita API-ja

Prije nego ubacim sigurnosnu zaštitu URL-ovima je moguće pristupiti neograničeno mnogo puta. Ovo nije problem kada, kao u ovom konkretnom slučaju, šaljem mali json objekt, ali kada je u pitanju API koji dohvaća više podataka iz npr. SQL baze onda to već postaje problem jer može doći do zagušenja ili potpunog blokiranja servera.

Sada ću dodati apiLimiter objekt s nekoliko parametara.

Ako želim da se ta pravila primjene na sve krajnje točke (endpoint) dodajem sljedeće:

Mogu vidjeti da je svaki sljedeći upit sporiji od prethodnog i da se nakon 5 poslanih upita prikazuje poruka iz apiLimiter objekta.

ExpressJS Rate Limit – zaštita API-ja

U slučaju da za svaku krajnju točku tj. svaki endpoint želim postaviti drugačiji uvijet to radim tako da kreiram toliki broj objekata koliko ima krajnjih čvorova. Npr.

Nodemailer & NodeJS – API za slanje emaila

Cilj ovog blog posta je pokazati kako napraviti API za slanje emaila. To ću postići koristeći NodeJS, ExpressJS, Nodemailer i naravno Gmail.

Postavljanje projekta

Kreiram mapu za projekt i unutar nje pokrećem naredbu

i odmah nakon toga instaliram potrebne NPM pakete:

Express.js: $ npm install express --save
Nodemailer: $ npm install nodemailer--save
bodyParser: $ npm install body-parser -save

Struktura projekta prema package.json sada izgleda ovako:

Sada imam sve spremno za kreiranje datoteke unutar koje će se nalaziti logika API-ja.

API sada mogu i pokrenuti te se uvjeriti da radi. Pokrećem ga naredbom u kojoj riječ “index” označava naziv .js datoteke.

Nodemailer & NodeJS – API za slanje emaila

To je mogla biti i npr. server.js datoteka. U tom bi slučaju API pokrenuo naredbom $ node server.

Na adresi http://localhost:8080/api mogu vidjeti da je API uspješno pokrenut.

Nodemailer & NodeJS – API za slanje emaila

Slanje testnog e-maila

Unutar datoteke index.js sada ću kreirati API za slanje e-maila.

S obzirom na parametar secureConnection: false vrlo je važno da omogućim dopuštanje nesigurnijim aplikacijama da pristupe računu na adresi https://myaccount.google.com/security?pli=1

“Less Secure Apps” - Google

Jer ako to ne napravim dobit ću poruku o grešci što znači da e-mail neće biti poslan/primljen. Ovaj dio mi je zadavao najviše problema prije dvije godine kada sam prvi put radio Nodemailer API. U pitanju je bila funkcionalnost vezana uz resetiranje lozinke.

Nodemailer & NodeJS – API za slanje emaila

Ako sada putem Postmana pokrenem POST zahtjev na adresu http://localhost:8080/api/posaljiEmail vrlo brzo će mi stići e-mail.

Nodemailer & NodeJS – API za slanje emaila

Zašto se u slici iznad kao adresa primatelja nalazi drugačija adresa od one navedene gore u API-ju? To je zbog postavki unutar Gmaila gdje je navedeno da je adresa k*n*a*t@tomislavstankovic.com zadana adresa pošiljatelja. S obzirom da ovdje koristim Gmail kao servis za slanje e-maila jasno je da će on uzeti te zadane postavke.

Nodemailer & NodeJS – API za slanje emaila

E-mail sa “pravim” podacima

U gornjem sam se primjeru uvjerio da moj Nodemailer API uredno radi, a sada želim imati mogućnost određivanja na koju adresu i koji sadržaj želim poslati.

API sada izgleda ovako:

Nodemailer & NodeJS – API za slanje emaila

Ovdje se može vidjeti da podatke šaljem kroz req.body i upravo je to razlog zbog kojeg koristim body-parser. U slučaju da nisam koristio body-parser dobio bi sljedeću grešku.

Ovdje se može vidjeti da podatke šaljem kroz <span class="lang:js decode:true  crayon-inline">req.body</span> i upravo je to razlog zbog kojeg koristim <strong><em><a href="https://www.npmjs.com/package/body-parser" rel="noopener" target="_blank">body-parser</a></em></strong>. U slučaju da nisam koristio <em>body-parser</em> dobio bi sljedeću grešku.

Također, ako ne unesem sve potrebne podatke body-parser neće imati s čime raditi i opet ću dobiti grešku. U ovom slučaju nisam poslao e-mail adresu primatelja.

Nodemailer & NodeJS – API za slanje emaila

Nakon što unesem sve potrebne podatke, body-parser će odraditi svoje i e-mail će biti uspješno poslan/primljen.

Nodemailer & NodeJS – API za slanje emaila

Node.js RESTful API za upload datoteka

Ovaj blog post je nastavak prošlog u kojemu smo izradili jednostavan RESTful API koristeći Node.js i Express.js.

Ondje smo imali tablicu sa korisnicima i upravljali jednostavnom formom s dva tekstualna polja tj. kroz API smo dodavali ime i prezime korisnika, uređivali ih i brisali. U ovom primjeru API-ju ćemo dodati mogućnost dodavanja datoteka koje će se spremati na disk.

Kako bi jednostavnije mogli pratiti sadržaj ovog blog posta preuzmite API iz prošlog blog posta.

Početna struktura projekta:

Nadogradnja MySQL baze

Za početak ćemo dodati dva nova polja u bazu, k_slika i k_dokument, koja će nam služiti za povezivanje datoteka s određenim korisnikom. U oba polja će se spremati putanje do datoteka, iako sliku možemo spremati i kao base64 string, ali kako to nije najbolja praksa nećemo to raditi.

Polja za datoteke u bazi

multer middleware

Kako bi API razumio što mu želimo reći kada šaljemo datoteke koristiti ćemo multer NPM paket. Paketa s istom svrhom ima više nego dovoljno da možete odabrati i neki drugi ako zaključite da vam više odgovara. Koji god koristili princip je isti, a tiče se multipart/form-data.

U mapi projekta instalirati ćemo novi paket pomoću naredbe $ npm install --save multer

Struktura projekta sada je bogatija za mapu multer:

Kao i package.json

Međutim, naš API još uvijek ne može koristiti multer, barem dok ga ne navedemo u server.js što ćemo sada i učiniti.

Server.js

U server.js dodajemo sljedeće:

Prva linija definira varijablu kojom pozivamo ranije dodani paket dok druga linija definira mapu u koju će se spremati datoteke koje budu dodane putem API-ja. Ta će se mapa stvoriti čim sljedeći put pokrenemo server.js, a nalazit će se unutar root mape KorisniciAPI.

multer uploads datoteka

Dodavanje korisnika i upload datoteka

API za dodavanje korisnika sada će dobiti neke nove mogućnosti.

Sada ćemo pomoću Postmana dodati jednog korisnika, njegovu sliku i datoteku pa ćemo analizirati proces i rezultat.

Multer upload datoteka

Kao što se vidi iz gornje animacije, nakon što kliknemo na Send i pošaljemo ime, prezime, sliku i datoteku korisnika sve se zapiše u bazu podataka u obliku stringa.

console.log(req.body); i console.log(req.files); daju nam vrlo korisne informacije. Kao prvo možemo potvrditi da je sve što smo poslali putem Postmana i stiglo, a kao drugo možemo vidjeti od čega se sastoje naše datoteke i odlučiti u kojem ćemo ih obliku spremati u bazu podataka. U ovom slučaju koristimo destination i filename .

Sliku tj. datoteku na frontendu možemo prikazati u obliku: http://localhost:8080/destination/filename

I to je to što se dodavanja datoteka tiče. Nakon što smo se uvjerili da API radi možemo izraditi formu za unos sadržaja koju će koristiti korisnici.

Brisanje korisnika

Korisnika možemo obrisati korištenjem postojećeg API-ja. I kao što se vidi u prethodnom blog postu kada pošaljemo ID korisnika sve vezano uz njega briše se iz baze. Međutim ostaje jedan problem, a to su datoteke na disku koje nisu obrisane jer API-ju smo rekli da iz baze obriše samo korisnika s određenim ID-em, ali API neće i ne zna obrisati fizičke datoteke koje se nalaze na disku.

Brisanje datoteka s diska

Kako bi to bilo moguće potrebno je koristiti Node File System (fs). Na vrhu server.js definirat ćemo varijablu var fs = require('fs');

API za brisanje korisnika sada izgleda ovako:

Osim ID-ja korisnika sada šaljemo još i naziv slike tj. naziv dokumenta http://localhost:8080/api/korisnik/2/6527f85adbde49f692efd52449764547/ad6375db29809af74be25b2d8822f46f tako da smo ta dva nova parametra morali navesti i unutar API-ja '/korisnik/:k_id/:k_slika/:k_dokument'.

Kada pokrenemo API dobijemo console.log(req.params):

i { "success": true }

Cijeli proces izgleda ovako:

NodeJS brisanje datoteka

Zaključak

Ovo je samo jedan od načina kako pomoću NodeJS-a napraviti upload i brisanje datoteka.

Posjetite GitHub i preuzmite projekt.

Izrada RESTful API-ja koristeći Node.js i Express.js

Kroz ovaj blog post pokazati ću kako napraviti jednostavan RESTful API koristeći Node.js i Express.js. Pomoću API-ja povezati ćemo se sa MySQL bazom, prikazati popis korisnika te urediti i brisati korisnike, a sve ćemo testirati pomoću Postmana.

Uz pretpostavku da imate instaliran Node.js možemo krenuti.

Postavljanje projekta

Kao i u prošlom blog postu, i ovdje prvo moramo postaviti projekt. Za početak ćemo kreirati mapu projekta koja će se zvati KorisniciAPI. Nakon toga unutar mape projekta pokrećemo naredbu $ npm init --yes kako bi dobili package.json

Kako bi ovaj API radio ono što smo zamislili moramo dodati nekoliko NPM paketa, a to su:

Nakon instalacije primijetit ćete dvije stvari, a to su nova mapa node_modules i promjena unutar package.json.

Server.js

Sada znamo da će prilikom pokretanja Node.js tražiti server.js pa ga idemo napraviti.

Struktura projekta sada izgleda ovako i više se neće mijenjati, osim sadržaja unutar server.js:

API pokrećemo naredbom

Nakon što smo testirali naš API pomoću rute http://localhost:8080/api zaključujemo da je sve u redu i možemo krenuti dalje.

API test

MySQL baza i korisnici

Sada ćemo napraviti MySQL bazu podataka naziva korisniciapi s poljima k_id, k_ime i k_prezime.

MySQ Lkorisnici

Kako bi našu MySQL bazu povezali sa server.js moramo dodati sljedeće:

Sada imamo sve što nam je potrebno kako bi mogli napraviti rute za dodavanje (POST), dohvaćanje (GET), uređivanje (PUT) i brisanje (DELETE) korisnika.

Middleware

Ako želimo da se nešto dogodi svaki put kada naš API dobije nekakav zahtjev onda koristimo middleware. Za potrebe ovog primjera stavit ćemo da nam console.log() poruku.

Kreiranje ruta

Krećemo s izradom ruta za naše korisnike.

Dodavanje korisnika

POST http://localhost:8080/api/dodajkorisnika

API za dodavanje korisnika

Dohvaćanje svih korisnika

GET http://localhost:8080/api/pregledkorisnika

Dohvaćanje svih korisnika

Uređivanje jednog korisnika

PUT http://localhost:8080/api/korisnik/:k_id

Uređivanje jednog korisnika

Brisanje jednog korisnika

DELETE http://localhost:8080/api/korisnik/:k_id

Brisanje jednog korisnika

Zaključak

Ovo su osnove osnova kada je u pitanju izrada APi-ja. Nismo se dotaknuli pitanja sigurnosti, autentifikacije korisnika niti pokušali slati datoteke, npr. slike od korisnika, pomoću API-ja. Možda o tome bude riječi nekom drugom prilikom.

Naravno da kada budete radili kompleksniji sustav nećete sve rute staviti u server.js nego će svaka ruta imati svoju datoteku.

Posjetite GitHub i preuzmite projekt.