a) Asenna koneellesi Docker, ellei sitä ole jo asennettu.
b) Asenna MySQL ja PHPMyAdmin tämän docker-compose.yml -tiedoston avulla. Luo PHPMyAdminilla tietokanta nimeltään "koetietokanta", ja luo siihen yhteys tämän koodin avulla.
c) Asenna MongoDB ja luo "koetietokanta" tämän ohjeen avulla. Luo siihen yhteys tämän koodin avulla.
Jos Docker ei toimi koneellasi, voit asentaa tietokannat lokaalisti XAMPP:in(MySQL eli MariaDB) tai MongoDB ohjeen(MongoDB) avulla. MongoDB:tä on myös mahdollista käyttää ilmaisen MongoDB Atlas -pilvipalvelun kautta, jolloin sitä ei tarvitse asentaa lainkaan omalle koneelle.
Palauta tehtävän ratkaisuna kaksi kuvankaappausta konsolista, joissa näkyy, että yhteydet MySQL:ään ja MongoDB:hen toimivat
Luo uusi MySQL-tietokanta nimeltään nodemysql. Aja siellä nämä SQL-komennot joilla luodaan kannan taulut ja niiden välinen relaatio. Tee sitten tiedostot joiden ajaminen suorittaa seuraavat operaatiot MySQL-tietokannassa:
1. addstudent.js - lisää uuden opiskelijan. 2. findall.js hakee kaikki opiskelijat. 3. findbelowlimit.js - hakee opiskelijat joilla on opintopisteitä alle määrätyn rajan. 4. deletestudent.js - poistaa opiskelijan opiskelijatunnuksen perusteella. 5. updatepoints.js - muokkaa opiskelijan opintopisteitä. 6. addgrade.js - lisää opiskelijalle uuden arvosanan, 7.updategrade.js - muokkaa opiskelijan kurssin arvosanaa.
HUOM! Seuraavat kolme seikkaa on huomioitava: 1) SQL-kyselyt tulee tehdä metodikirjaston metodien sisälle. Metodikirjaston nimi voi olla esim. Dbmethods. Kts. Dbmethods.js-malli jossa on yksi metodi. Ajettavat js-tiedostot kuten addstudent.js eivät saa sisältää SQL:ää vaan toimenpiteet suoritetaan kutsumalla metodeja metodikirjastosta. Kts. addstudent.js-malli. 2) Jos poistat opiskelijan, pitää ensin poistaa kaikki hänen arvosanansa. Tee sitä varten Dbmethods-olioon deleteGrades-metodi 3) Jos lisäät opiskelijalle addGrade-metodilla arvosanan 1-5, pitää opiskelijan opintopistemäärää lisätä viidellä addPoints-metodin avulla (oletamme yksinkertaistaen että jokainen kurssi on laajuudeltaan 5op). Toteuta tämä transaktion avulla (kts. malliesimerkki). Tietokannan transaktio on siis yhtenä toimenpiteenä toteutettava tietokantaan kohdistuvien toimenpiteiden sarja (tässä 2 kpl eli addGrade() ja addPoints()), jossa jonkin osan epäonnistuessa koko toimenpidesarja peruutetaan. Vihje: transaktio kannattaa ehkäpä tehdä addgrade.js -tiedostoon, mutta sen metodit tehdään Dbmethods-metodikirjastoon. Tällöin koodi on selkeämpää, varsinkin kun transaktio pitää sulkea ehdon sisään (if grade>0 { //transaktio} else { // pelkkä arvosanan lisäys }).
Sovellukseen ei tarvitse tehdä minkäänlaista käyttöliittymää. Sovellus ei tarvitse myöskään web-serveriä, koska tietoja ei esitetä web-sivuilla. Riittää että tiedostoja konsolissa ajamalla suoritetaan edellä mainitut kantaoperaatiot. Apua saat tästä tutoriaalista ja SQL-komentojen dokumentaatiosta. Huomaa, että tehtävässä kantaoperaatioiden tulosten asynkroninen talteenotto tapahtuu perinteiseen tyyliin callbackien avulla. Toinen vaihtoehto on promisen käyttö.
Voit tehdä ratkaisut tähän kansioon. Voit kokeilla test-kansiossa olevia testejä. Testitietokanta ja tehtävän toteutuksessa käytetty kanta ovat tässä tapauksessa sama kanta, koska kyseessä on vain harjoitustehtävä.
Kokeillaan MongoDB:n käyttöä Nodejs-koodilla merkkipohjaisessa käyttöliittymässä, ajamalla tiedostoja samaan tyyliin kuin MySQL-tehtävässä. Käytetään MongoDB-kantaa Mongoose ODM-kirjaston avulla.
Tee tietokanta nimeltään studentdb ja sille tunnarit tämän ohjeen avulla. Kantayhteyden muodostavan urlin voit laittaa .env-tiedostoon, kuten mongoose_basics-esimerkissä on tehty. Tee erillinen dbconnection.js-tiedosto, jossa otat kantayhteyden. Sen voit liittää tiedostoihin, joissa sitä tarvitaan.
Tee kansioon models tiedostot Student.js ja Grade.js. Tee Student.js-tiedostoon Mongoose-skeema, jonka nimi on esim. StudentSchema. Skeeman kentät ovat: studentcode, name, email, studypoints ja grades. Tee tästä skeemasta model ja exporttaa se. Tee Grade.js-tiedostoon GradeSchema. Alidokumentin skeemassa ovat kentät: coursecode ja grade. Exporttaa GradeSchema (älä tee siitä modelia) ja käytä sitä Student.js-tiedoston skeemassa. Tässä ovat skeemojen rungot, joihin voit tehdä kenttien määritykset.
Tee sitten tiedostot, joiden ajaminen suorittaa seuraavat operaatiot Mongodb-tietokannassa:
1. addstudent.js - lisää uuden opiskelijan. 2. findall.js hakee kaikki opiskelijat. 3. findbelowlimit.js - hakee opiskelijat joilla on opintopisteitä alle määrätyn rajan 4. deletestudent.js - poistaa opiskelijan opiskelijatunnuksen perusteella. 5. updatepoints.js - muokkaa opiskelijan opintopisteitä. 6. addgrade.js - lisää opiskelijalle uuden arvosanan (vihje: $push-komento) ja samalla lisää opintopisteitä viidellä (vihje $inc-komento). Tähän ei siis tarvita transaktiota. 7.updategrade.js - muokkaa opiskelijan kurssin arvosanaa (vihje: grades.$.grade).
Sovellukseen ei tarvitse tehdä käyttöliittymää, vaan riittää että tiedostoja konsolissa ajamalla suoritetaan edellä mainitut kantaoperaatiot. Apua saat mongoose_basics-esimerkistä, tästä tutoriaalista ja Mongoosen sekä Mongodb:n kyselyiden ja komentojen dokumentaatiosta. HUOM! Mongoosen versiosta 7 alkaen modelin metodit palauttavat pelkästään promisen, eli modelin metodin tuottamaa tulosta ei voi enää ottaa talteen pelkällä callbackilla. Käytä siis then()-metodia tai async-awaitia.
Voit tehdä ratkaisut tähän kansioon, jossa ovat myös testit. Testitietokanta ja tehtävän toteutuksessa käytetty kanta voivat tässä tapauksessa olla sama kanta koska kyseessä on vain harjoitustehtävä.
Jatka tätä Express-sovellusta siten että teet siihen kolmannen EJS-sivun (valmiina tässä), jolle kirjaudutaan session avulla, samoin kuin kahdelle muulle sivulle.
Kolmannella sivulla näytetään kaikki edellisen tehtävän mongodb -kannassa olevat opiskelijat ja heidän arvosanansa. Tämä onnistuu lisäämällä tietokantahaku siihen index.js:n reittiin, jossa siirrytään kolmannelle sivulle. Tarvitset tietysti myös tietokantayhteyden ja mongoose-modelit, jotka voit kopioida edellisestä tehtävästä. HUOM! Mongoosen versiosta 7 alkaen modelin metodit palauttavat pelkästään promisen, eli modelin metodin tuottamaa tulosta ei voi enää ottaa talteen pelkällä callbackilla. Käytä siis then()-metodia tai async-awaitia.
Tämä sovellus on siis ns. perinteinen käyttöliittymän sisältävä backend-sovellus. Käyttöliittymäsivut ovat backendin viewissä, niiden koodi suoritetaan backendissä ja suorituksen tulos, eli valmiiksi rakennetut HTML-sivut, lähetetään selaimelle.
Tee harjoituksessa 2. luomallesi MongoDb-opiskelijatietokannalle Expressillä REST-serveri jonka tarjoamaa apia testaat Postmanilla. Tässä vaiheessa ei tarvitse siis tehdä lainkaan frontendiä eli REST-clientia. REST-serverin toiminnot ovat seuraavat: 1) Kaikkien opiskelijoiden haku. 2) Yhden opiskelijan haku id:n perusteella. 3) Yhden opiskelijan haku opiskelijanumeron perusteella. 4) Opiskelijan lisäys. 5) Opiskelijan poisto. 6) Opiskelijan muokkaus. 7) Niiden opiskelijoiden haku joilla on opintopisteitä alle url-osoitteessa lähetetyn arvon. 8) Uuden arvosanan lisäys opiskelijalle ja samalla opintopisteiden lisäys viidellä. 9) Arvosanan muokkaus. 10) Niiden opiskelijoiden haku joilla on tietty kurssi (vihje: MongoDB:n $elemMatch tai Mongoosen aggregaatti). HUOM! Mongoosen versiosta 7 alkaen modelin metodit palauttavat pelkästään promisen, eli modelin metodin tuottamaa tulosta ei voi enää ottaa talteen pelkällä callbackilla. Käytä siis then()-metodia tai async-awaitia.
Voit käyttää pohjana tässä restapi-projektissa olevaa express-sovelluksen rakennetta. Rakenne noudattaa arkkitehtuuria, jossa routes-kansiossa olevassa reititystiedostossa tehdään pelkkä reititys ja mongoose-kantaoperaatiot ovat kontrollerissa, kuten tässä tutoriaalissa on tehty. Tyhjien kansioiden ja tiedostojen sisällön voit kopioida edellisestä tehtävästä. Huomaa että edellisen tehtävän routes/index.js-tiedoston reitit ja views-kansion sivutemplaatit ovat tässä sovelluksessa turhia. Tee opiskelijoille oma reititystiedostosto, jonka nimi on students.js. Opiskelijoita käsittelevät tietokantaoperaatiot tehdään tiedostoon studentcontroller.js, jonka pohja on jo tehty restapi-projektin controllers-kansioon. Students.js-reititystiedosto käyttää studentcontroller.js:n metodeja.
Jatketaan edellistä tehtävää. Tee edellisen tehtävän POST, DELETE ja PUT -reitteihin autentikaatio ja authorisaatio JWT:llä (tässä malliksi router-tiedosto jossa on authorisaatio). Autentikaatiossa eli sisäänkirjautumisessa tapahtuvassa tunnistautumisessa, ei tässä tapauksessa ole käyttöliittymää, vaan käyttö tapahtuu Postmanilla. Postmanilla mennään ensin autentikaatioreittiin jonne postataan tunnus ja salasana jolloin saadaan JWT-token. Kun esim. postataan uusi opiskelija, laitetaan Postmanissa opiskelijan tietojen lisäksi headerin mukana avain x-access-token ja sen arvona JWT-tokenin arvo (ilman lainausmerkkejä). Kun oikea JWT-tokenin arvo on lähetetty ja authorisaatio, eli valtuutus toimintojen käyttöön, on suoritettu, niin sen jälkeen opiskelijan postaus onnistuu.
Mallia tehtävän tekemiseen saat esim. tästä tutoriaalista. Tehtävän ratkaisemisen helpottamiseksi voit käyttää tätä valmista koodia joka on tehty edellä mainitun tutoriaalin pohjalta. Se sisältää tokenin luonnin ja verifikaation sekä kontrollerin jossa on käyttäjän rekisteröinti- ja autentikaatiometodit. Lisäksi mukana on User-model, jotta voit tallentaa käyttäjiä tietokannan users-collectioniin.
Sovelluksen tietoturvaa parannellaan myös kahdella muulla tavalla: Tee .env-tiedostoon muuttuja SECRET, johon laitat itse keksimäsi secret keyn. Tämä on tokenin secret key, jolla varmistetaan että token tulee oikealta palvelimelta. Sitä käytetään koodissa samalla tavalla kuin .env-tiedostossa olevaa tietokannan urlia. Käyttäjän salasana salataan bcrypt-kirjaston avulla ennen kuin se laitetaan kantaan, ja salaus puretaan kun salasana haetaan kannasta.
Huomaa että edellisessä tehtävässä ollut testi, jossa testattiin uuden opiskelijan luontia, ei mene enää läpi ellei samassa post-pyynnössä lähetetä myös tokenia. Testi menee läpi kun lisäät testissä lähetettävän JSON-tiedoston viimeiseksi kentäksi "token": "tokenin arvo", eli token voidaan ottaa silloin siitä.
Yhdistä tehtävässä 5. tekemäsi suojattu REST-backend tähän valmiiseen Angular-frontendiin, jonka käynnistät omassa projektissaan (npm start). Frontendissä on JWT-autentikaatio. Yhdistäminen vaatii seuraavat toimenpiteet: 1) laita cors-moduuli palvelinsovellukseen (app.js) toimimaan jotta cross-domain -tiedonsiirto onnistuu. 2) Laita Angular-frontendin serviceissä olevat url-osoitteet viittaamaan omalle serverillesi. Viittausten pitäisi olla valmiiksi oikeita, mutta tarkista ne. 3) Muuta tarvittaessa palvelinpuolella kontrollereiden metodit sellaisiksi että ne palauttavat pyyntöjen tuloksen JSON-muodossa (esim. muuta res.send('onnistui') -> res.json(result)).
Kun on valmista, käynnistät palvelinsovelluksen ja asiakassovelluksen, ja menet sovellukseen sisään asiakassovelluksesta.
Tehtävän tarkoituksena on vain demota frontendin ja backendin yhteistoimintaa. Frontend on yksinkertaistettu eli siitä puuttuu opiskelijan arvosanojen (grades) käsittely. Huomaa myös että frontendissä ei ole lomakedatan validointia. Jos frontend ei toimi, voi syynä olla se että yrität syöttää lomakkeille dataa joka ei sovi backendin skeemaan. Tästä näet virheilmoituksen backendin konsolissa. Huomaa, että myöskään backendissä ei ole kunnolla tehtyä virheenkäsittelyä. Mallin siihen saat esim. tästä.
Tehdään tehtävän 5 suojattuun REST-APIin Google-autentikaatio. Ensin luodaan login-applikaatio Google cloudiin tämän ohjeen mukaisesti. Ota sitten pohjaksi tehtävässä 5. tekemäsi sovellus ja katso mallia Express-passport-google-2 -esimerkistä. Muuta tehtävässä 5. tekemäsi sovellus sellaiseksi että teet sinne views-kansioon index.ejs-tiedoston, jossa loggaudut sisään Googlen tunnareilla salaiselle profile.ejs -sivulle. Saat index.ejs:n ja profile.ejs:n valmiina Express-passport-google-2 -esimerkistä. Kun olet päässyt /profile -reittiin, luot kyseisessä reitissä JWT-tokenin johon laitat Googlelta saadun Google id -tunnuksen. Google id:n sijasta JWT-tokenissa voitaisiin käyttää myös Gmail-osoitetta, mutta Google id on tietoturvan kannalta parempi. Tämän JWT-tokenin avulla pääset suojattuihin students-reitteihin. Tulosta JWT-token profile.ejs -sivulle. Voit nyt kopioida sivulle tulostuvan JWT-tokenin ja pastettaa sen Postmaniin, kun menet suojattuihin reitteihin Postmanilla. Sovellus on siis samanlainen REST-API, kuin harjoituksen 5. sovellus, mutta erona on Google-kirjautuminen ja JWT-tokenin poiminta käsin webbisivulta.
Kerro lyhyesti miten toteuttaisit sosiaalisen Google-loginin full stack -sovellukseen, niin että kirjautuminen tapahtuu Angular-sovelluksesta ja tietyt REST API -reitit ja Angular-sovelluksen SPA-näkymät on suojattu. Tätä toiminnallisuutta ei tarvitse tässä tehtävässä toteuttaa käytännössä, mutta olisi hyvä jos osaisit kertoa kuinka lähtisit toteuttamaan sitä. Voit katsoa mallia kurssin esimerkeistä.
Tee tämä tutoriaali, jossa rakennat gatewayn, jonka kautta pääsee käsiksi kahteen tai useampaan mikropalveluun. Liitä tekemääsi gatewayhin Nestjs-mikropalveluesimerkissä esitetty mikropalvelu, jonka nimeksi voit antaa "rocket-microservice". Tee lisäksi uusi mikropalvelu, joka laskee summan sille lähetetyistä numeroista. Sen nimeksi voit antaa "sum-microservice". Mallin sen tekemiseen saat Nestin perusesimerkistä. Liitä tämäkin mikropalvelu gatewayhin. Testaa gatewayn osoitteesta http://localhost:3000/tunniste, että mikropalvelut toimivat. Kommentoi mikropalveluiden ja gatewayn tiedostoihin niiden roolit sovelluksen arkkitehtuurissa.
Tee tämän yksinkertaisen chatin ja tämän tutoriaalin koodeja soveltamalla yksinkertainen numeronarvauspeli jota voi pelata kaksi tai useampi pelaaja samanaikaisesti. Tarkoituksena on siis arvata numero joka on arvottu tietyltä väliltä. Pelaajat saavat satunnaisesti luodun nimen, kirjoittavat arvauksia tekstikenttään jonka alapuolelle ilmaantuvat nimet, arvaukset ja tieto siitä oliko arvaus liian suuri tai pieni. Ensimmäisenä oikean luvun arvannut pelaaja voittaa pelin. Tutoriaali on erittäin vanha, joten sen soveltaminen on hyvää harjoitusta.
Julkaistaan webissä tehtävässä 5. tehty suojattu REST-API. Käytetään kahta pilvipalvelua, joiden ilmainen käyttö ei vaadi mitään muuta kuin rekisteröitymisen.
1) Luodaan MongoDB -tietokanta MongoDBAtlas
-pilvialustalle:
-Luo ilmainen klusteri, AWS Frankfurt on hyvä sijainti
-Luo Collections-napista kanta ja collectionit (studentdb sekä
students ja users)
-Luo Database Access -välilehdellä tunnarit
-Salli Network Access -välilehdellä pääsy kantaan tietyistä tai
kaikista IP-osoitteista.
-Paina Connect-nappia ja ota talteen osoite, jolla voit yhdistää
kannan omaan sovellukseesi
-Vaihda MongoDbAtlas-kannan osoite omalla koneellasi sijaitsevaan
sovellukseen (tehtävä 5. ratkaisu), ja testaa Postmanilla että
sovelluksesi toimii pilvitietokannan kanssa.
2) Asennetaan harjoituksessa 5. tehty backend-sovellus Render- tai Netlify-pilvipalveluun. Kokeile julkaisua ensin hyvin yksinkertaisella Express-sovelluksella, jossa on esim. vain yksi get-reitti, josta saadaan palvelimelta vastaus "Hello World!". Render on julkaisualustoista hieman helpompi käyttää, joten sitä ehkä kannattaa kokeilla ensin. Rekisteröidy, ja valitse ilmainen hobby- tai starter-plan.
Renderin kanssa voit käyttää apuna tätä ja tätä ohjetta. Netlifyn kanssa voit käyttää apuna tätä ja tätä ohjetta.
Huomaa että Netlifyssä julkaistavaan sovellukseen pitää tehdä pieniä muutoksia, sillä julkaisun apuna käytetään Netlifyn omia serverless-funktioita. Nodemon tulee poistaa sovelluksesta. Huomaa, että kun sovellus laitetaan julkisesti esille, vain datan haku (GET) saa olla REST-APIssa kaikille käyttäjille avoin. Muissa reiteissä on ehdottomasti oltava autentikaatio, tai jos ei ole, niin muut reitit on suljettava kommentoimalla.
Kirjoita lyhyt dokumentti pilvipalveluiden käyttöönotosta ja asennuksen vaiheista. Testaa backendiä Postmanilla Sovelluksen REST-API-endpointeista.
Lopputyö on pieni Nodejs-sovellus, jossa sovellat kurssilla esitettyjä ja/tai web-lähteistä oppimiasi asioita. Lopputyössä saa käyttää webistä löytyviä tutoriaaleja sovelluksen pohjana, mutta siinä tapauksessa tutoriaalin sovellusta on laajennettava omalla koodilla. Lähteenä käytetty tutoriaali tulee ilmoittaa, ja itse tehty koodi tulee tuoda esille muun koodin seasta kommentoimalla. Lopputyössä ei tarvitse olla frontendiä, vaan Postman tai Nodejs-backendin view, kuten esim. ejs-templaatit, riittävät käyttöliittymäksi. Sovellusta ei tarvitse julkaista, vaan se voi toimia pelkästään omalta koneelta. Sovelluksen saa halutessaan tietysti myös julkaista esim. Renderissä. Lopputyön aiheen voi valita vapaasti, mutta sopivia aiheita voisivat olla esim. seuraavat:
Lopuksi täytä kurssipalaute Peppi-järjestelmässä. Kurssilta ei voi saada arvosanaa, ennen kuin kurssipalaute on annettu.
***