Last additions

This commit is contained in:
Marko Korhonen 2020-05-09 21:12:26 +03:00
parent 015c5db775
commit 09c2cf0074
No known key found for this signature in database
GPG key ID: 911B85FBC6003FE5
12 changed files with 104 additions and 34 deletions

12
tex/appendix/diesel.tex Normal file
View file

@ -0,0 +1,12 @@
\chapter{Tietokannan migraatiotiedostot}\label{appx:diesel}
\section{up.sql}
\begin{code}
\inputminted{SQL}{code/up.sql}
\end{code}
\section{down.sql}
\begin{code}
\inputminted{SQL}{code/down.sql}
\end{code}
\clearpage

View file

@ -52,4 +52,10 @@
description={Ohjelman palvelimella suoritettava osa, johon asiakaspuolen ohjelmisto yhdistyy}
}
\newglossaryentry{Full-stack}{
name={Full-stack},
plural={full-stack},
description={Sovellus, missä on toteutettu sekä asiakas- että palvelinpuolen ohjelmisto}
}
\glsaddall

View file

@ -19,7 +19,7 @@ Rustin yhtenä pääominaisuutena on mainostettu sen uudenlaista näkökulmaa mu
Koodiesimerkin \ref{code:rust:ownership} rivillä 9 tapahtuva ''name''-arvon tulostus ei toimi, koska arvon omistajuus on siirretty funktiolle ''say\char`_hello''. Funktion suorittamisen jälkeen se poistuu näkyvyysalueelta ja kaikki sen omistamat arvot vapautetaan muistista. Näin ollen arvoa ''name'' ei ole enää olemassa, kun sitä yritetään käyttää rivillä 9. Koodi saadaan toimimaan pienellä muutoksella.
\bigskip
\clearpage
\begin{code}
\inputminted{Rust}{code/borrow.rs}
@ -116,6 +116,8 @@ Rustia kehitettäessä on aina ollut tavoitteena luotettavuus. Tämä tarkoittaa
Myös Rustin kääntäjään on panostettu paljon, ja virheiden sattuessa se on todella hyvä työkalu ohjelmoijalle. Se alleviivaa ongelmakohdat ja selittää lyhyesti, mistä ongelma johtuu. Jossain tapauksissa kääntäjä jopa antaa pieniä koodin pätkiä, mistä voi olla apua ongelman ratkaisemisessa [koodiesimerkki \ref{code:rust:help}].
\clearpage
\begin{code}
\inputminted[linenos=false]{shell}{code/compiler-help}
\captionof{listing}{Rustin kääntäjä auttaa unohtuneen importin lisäämisessä}
@ -163,25 +165,29 @@ Metaohjelmointi avaa aivan uudenlaisia mahdollisuuksia sille, mitä ohjelmointik
\subsection{Dokumentaatio ja yhteisö}
Rust on tunnettu todella laajasta dokumentaatiostaan ja vahvasta yhteisöstään. Molemmista on paljon apua varsinkin aloittelijoille.
Aloitin itsekin opiskelemaan Rustia vain hieman ennen tämän insinöörityön alkua ja yhteisöstä oli monesti apua projektin aikana vastaan tulleissa ongelmissa.
Aloitin itsekin opiskelemaan Rustia vain hieman ennen tämän insinöörityön alkua. Yhteisöstä oli monesti apua projektin aikana vastaan tulleissa ongelmissa.
\subsection{Paketinhallinta}
\label{sect:paketinhallinta}
Rustin paketinhallinta on toteutettu Cargo-nimisellä ohjelmalla. Sitä voi käyttää koko ohjelmiston elinkaaren ajan aina projektin luomisesta sen julkaisemiseen. Cargon käsittelemiä paketteja kutsutaan laatikoiksi (eng. crate), jotka julkaistaan crates.io \cite{rust:cratesio} pakettirekisterissä. Laatikot voivat myös olla riippuvaisia toisista laatikoista. Laatikon tiedot ja riippuvuudet määritetään Cargo.toml-tiedostossa [koodiesimerkki \ref{code:rust:cargo-toml}].
\clearpage
\begin{code}
\inputminted{TOML}{code/Cargo.toml}
\captionof{listing}{Projektin palvelinpuolen Cargo.toml}
\label{code:rust:cargo-toml}
\end{code}
Cargoon on saatavilla myös useita liitännäisiä, esimerkiksi cargo-watch, joka suorittaa halutun toiminnon aina, kun projektin sisällä tapahtuu muutoksia sekä tässäkin projektissa käytetty cargo-web, joka helpottaa WebAssembly-ohjelmien kehittämistä.
Cargoon on saatavilla myös useita liitännäisiä, esimerkiksi cargo-watch, joka suorittaa halutun toiminnon aina, kun projektin sisällä tapahtuu muutoksia sekä tässäkin insinöörityössä käytetty cargo-web, joka helpottaa WebAssembly-ohjelmien kehittämistä.
\section{WebAssembly}
WebAssembly \cite{webassembly:home} on kehitteillä oleva asiakaspuolen ohjelmointikieli. Sitä on suunniteltu JavaScriptin seuraajaksi ja sen suurimpana etuna JavaScriptiin verrattuna on huomattavasti matalamman tason esitysmuoto, minkä ansiosta se on suorituskykyisempi.
Kehittäjän ei ole tarkoitus kirjoittaa WebAssemblya itse, vaan käyttää työkaluja, joilla olemassa olevia ohjelmointikieliä voi kääntää WebAssemblyksi. Rust on tästä hyvä esimerkki, sillä WebAssembly on yksi sen kääntäjän natiiveista ''targeteista'', samalla tavalla kuin vaikka x86-prosessorit.
\clearpage
WebAssembly on siis ensisijaisesti binääriformaatti, mutta sen voi muuntaa myös tekstiformaatiksi, jonka nimi on WebAssembly text \cite{webassembly:text}. WebAssembly text käyttää syntaksissaan S-lausekkeita \cite{s-expression}. Se on notaatio puurakenteiselle datalle, joka on kehitetty Lisp-ohjelmointikieltä varten, joten WebAssembly text muistuttaa syntaksiltaan hyvin paljon Lispiä. WebAssembly textiä käytetään tilanteissa, joissa ihmisen täytyy ymmärtää, mitä koodissa tapahtuu. Tätä hyödynnetään esimerkiksi WebAssemblyn sisäisessä kehityksessä ja web-ohjelmistojen debuggereissa.
\bigskip

View file

@ -1,5 +1,17 @@
\chapter{Projekti}
Tein insinöörityön yhteydessä full-stack projektin, jossa sekä palvelin- että asiakaspuolen ohjelmointi tehtiin Rustilla. Tarkoituksena ei ollut saada aikaiseksi mitään todella monimutkaista ohjelmaa, vaan puhtaasti arvioida Rustin soveltuvuutta web-ohjelmointiin.
Tein insinöörityön yhteydessä full-stack projektin, jossa sekä palvelin- että asiakaspuolen ohjelmointi tehtiin Rustilla.
\section{Tavoitteet}
Tavoitteena ei ollut saada aikaiseksi mitään todella monimutkaista ohjelmaa, vaan puhtaasti arvioida Rustin soveltuvuutta web-ohjelmointiin yksinkertaisella esimerkkiprojektilla.
\begin{figure}[h]
\centering
\includegraphics[width=\linewidth]{illustration/Architecture.pdf}
\caption{Projektin arkkitehtuurimalli}
\label{fig:architecture}
\end{figure}
Kuvassa \ref{fig:architecture} näkee sovelluksen arkkitehtuurin. Sovelluksen asiakaspuoli koostuu mallin keltaisista laatikoista ja palvelinpuoli sininisistä. Nuolet merkitsevät datan liikkumista, mikä on kaikkialla kaksisuuntaista.
\section{Kehitysympäristön asennus}
Rust-projektin aloittamiseksi kehittäjä tarvitsee koneelleen Rustin paketinhallintatyökalun, Cargon (katso luku \ref{sect:paketinhallinta}). Olen itse Linux-käyttäjä, joten sain asennettua Cargon Linux-jakeluni ohjelmavarastosta. Windows-käyttäjiä suosittelen käyttämään Rustup-asennusohjelmaa. Lisää tietoa Rustin asentamisesta saa Rustin kotisivuilta \cite{rust:install}.
@ -8,6 +20,8 @@ Projektin saa initialisoitua komennolla \mintinline{shell}{cargo init projektinn
Lähdekoodi sijaitsee hakemistossa ''src''. Cargo kirjoittaa hakemistoon valmiiksi ''main.rs'' -tiedoston, jossa on ''Hello world!'' esimerkkikoodi. ''main.rs'' on aina Rust-ohjelman ensimmäiseksi suoritettava tiedosto, eli niin kutsuttu entrypoint. ''main.rs''-tiedoston sisällä pitää olla ''main()''-funktio, josta ohjelman suoritus alkaa. Projektin voi suorittaa komennolla \mintinline{shell}{cargo run}.
\clearpage
Suosittelen asentamaan myös muutaman Cargon liitännäisen helpottamaan kehitystä. cargo-watchin avulla voi ajaa komennon aina, kun lähdekoodi muuttuu. Esimerkiksi komennolla \mintinline{shell}{cargo watch -x run} voi kääntää ja käynnistää projektin aina uudelleen, kun lähdekoodi muuttuu. cargo-add -liitännäisellä voi helposti lisätä uusia riippuvuuksia projektiinsa. Esimerkiksi Actix webin saa lisättyä komennolla \mintinline{shell}{cargo add actix-web}.
Näillä ohjeilla pääsee alkuun palvelinpuolen kehityksessä. Asiakaspuolen kehityksen käynnistäminen vaati vielä muutaman lisävaiheen, siitä lisää luvussa \ref{sect:asiakaspuoli:asennus}.
@ -20,7 +34,7 @@ Actix web on puolestaan rakennettu hyödyntämällä Actix-sovelluskehystä, jok
Actix web on myös hyvin integroitu Rustin vahvaan tyypitykseen. Erityisen vaikuttavaa oli se, että esimerkiksi tietyn rajapinnan päätepisteen POST-pyyntöön pystyy määrittämään parametriksi tietyn rakenteen (eng. structure) [koodiesimerkki \ref{code:rust:registeruser}].
\bigskip
\clearpage
\begin{code}
\inputminted{Rust}{code/registeruser.rs}
@ -42,14 +56,21 @@ Palvelinpuolen initialisointi ja käynnistäminen löytyvät liitteestä \ref{ap
\subsection{Todentaminen}
Actix webin modulaarisuus mahdollisti myös helposti tarvittavien väliohjelmistojen sisällyttämisen ohjelman toimintaan. Actix identity -paketista löytyi tarvittavat palikat, joilla sain lisättyä itse kirjoittamani käyttäjän todentamistoiminnallisuuden suojaamaan haluttuja reittejä.
Actix webin modulaarisuus mahdollisti myös tarvittavien väliohjelmistojen (eng. middleware) sisällyttämisen ohjelman toimintaan. Actix identity -paketista löytyi tarvittavat palikat, joilla sain lisättyä itse kirjoittamani käyttäjän todentamistoiminnallisuuden suojaamaan haluttuja reittejä.
Todentamiseen päätin käyttää JSON Web Tokeneita. Ne ovat standardoitu (RFC 7519\cite{jwt:home}) tunnistautumistapa verkossa. Tokenit ovat merkkijonoja, jotka sisältävät JavaScript-objekteja tekstimuodossa (JSON). Token koostuu kolmesta osasta \cite{jwt:home}: ylätunnisteesta (eng. header), hyötykuormasta (eng. payload) ja allekirjoituksesta (eng. signature).
Todentamiseen päätin käyttää JSON Web Tokeneita. Ne ovat standardoitu (RFC 7519\cite{jwt:home}) tunnistautumistapa verkossa. Tokenit ovat merkkijonoja, jotka sisältävät JavaScript-objekteja tekstimuodossa (JSON). Token koostuu kolmesta osasta \cite{jwt:home}: ylätunnisteesta (eng. header), hyötykuormasta (eng. payload) ja allekirjoituksesta (eng. signature). JSON Web Tokenin kaikki osat on havainnollistettu kuvassa \ref{fig:jwt}.
\begin{figure}[h]
\centering
\includegraphics[width=\linewidth]{illustration/jwt.png}
\caption{JWT:n osat havainnollistettuna käyttämällä jwt.io -sivustoa \cite{jwt:home}}
\label{fig:jwt}
\end{figure}
\bigskip
Ylätunniste koostuu JSON-objektista [koodiesimerkki \ref{code:json:jwt-header}], missä on määritelty tokenin tyyppi (tässä tapauksessa "JWT") ja allekirjoituksen algoritmi, mikä voi olla joko HS256 tai RSA.
\clearpage
\begin{code}
\inputminted{Rust}{code/jwt-header.json}
\captionof{listing}{JSON Web Tokenin ylätunniste}
@ -73,50 +94,58 @@ Tokenin toisessa osassa, hyötykuormassa, on itse tokenin sisältö [koodiesimer
Tokenin kolmesta osasta viimeinen on allekirjoitus. Se on koostettu ylätunnisteessa [koodiesimerkki \ref{code:json:jwt-header}] määritellyllä algoritmilla käyttämällä parametreina tokenin hyötykuormaa [koodiesimerkki \ref{code:json:jwt}] ja vain palvelimen tiedossa olevaa salasanaa. Koko tokenin turvallisuus perustuu juuri tähän allekirjoitukseen. Sen avulla palvelin voi varmistua siitä, että tokenia ei ole muokannut kukaan, kenellä ei ole tätä salasanaa.
Tokenia varmennettaessa hyötykuorma allekirjoitetaan uudelleen ja tätä uutta allekirjoitusta verrataan tokenin mukana tulleeseen allekirjoitukseen. Jos ne ovat samat, palvelin voi olla varma siitä että tokenin sisältöön voi luottaa. Tämän edellytyksenä tietysti on, että salasanaa on säilytetty turvallisella tavalla. JSON Web Tokenin kaikki osat on havainnollistettu kuvassa \ref{fig:jwt}.
\clearpage
\begin{figure}[h]
\centering
\includegraphics[width=\linewidth]{illustration/jwt.png}
\caption{Kaikki JWT:n osat havainnollistettuna käyttämällä jwt.io -sivustoa \cite{jwt:home}}
\label{fig:jwt}
\end{figure}
\bigskip
Tokenia varmennettaessa hyötykuorma allekirjoitetaan uudelleen ja tätä uutta allekirjoitusta verrataan tokenin mukana tulleeseen allekirjoitukseen. Jos ne ovat samat, palvelin voi olla varma siitä että tokenin sisältöön voi luottaa. Tämän edellytyksenä tietysti on, että salasanaa on säilytetty turvallisella tavalla.
Otetaan esimerkkinä tämän sovelluksen käyttäjä Pasi. Pasi ei ole ylläpitäjä, mutta hän koittaa tehdä itsestään ylläpitäjän muuttamalla omasta tokenistaan parametrin \mintinline{JavaScript}{"admin": false} arvoksi \mintinline{JavaScript}{true}. Kun Pasi lähettää tämän muokatun tokenin palvelimelle, se viedään JWT-validointifunktioon. Palvelin huomaa, että token ei ole enää validi, koska sen sisältöä ei ole allekirjoitettu palvelimen salasanalla.
Päätin tallettaa edellä mainitun JSON Web Tokenin evästeeseen (eng. cookie), joka on standardi tapa tallettaa juuri tällaisia todentamiseen käytettäviä tietoja selaimissa. Evästeiden käyttämisen etu on se, että selain huolehtii sen tallettamisesta automaattisesti ilman lisätoimia kehittäjältä. Lisäksi selain sisällyttää sen seuraaviin kutsuihin automaattisesti.
Projektin koko JWT-toteutus on liitteessä \ref{appx:jwt}.
Projektin JWT-toteutus on liitteessä \ref{appx:jwt}.
\subsection{CORS}
Lisäsin palvelimelle myös Cross-Origin Resource Sharing (CORS) \cite{wiki:cors} -toiminnallisuuden. Oletuksena selaimen lataama ohjelma saa ladata resursseja vain samasta osoitteesta, kuin mistä itse ohjelma on ladattu. Tämä on turvallisuuskäytäntö, joka kulkee nimellä Same-origin policy (SOP) \cite{wiki:sop}. Näihin resursseihin sisältyvät muunmuassa CSS-tyylimääritykset, kuvat ja JavaScript-ohjelmat.
Lähes kaikki nykyiset web-ohjelmistot kuitenkin vaativat näiden ulkoisien resurssien käyttöä. CORS on tekniikka, jossa palvelin kertoo selaimelle sallitut osoitteet, mistä resursseja saa noutaa. CORS:n lisääminen tähän projektiin hoitui Actixin liitännäisellä actix\char`_cors.
\bigskip
\begin{figure}[h]
\centering
\includegraphics[width=\linewidth]{illustration/CORS.pdf}
\caption{Esimerkki Cross Origin Resource Sharing -tekniikasta}
\caption{Esimerkki Single origin policy -turvallisuuskäytännöstä}
\label{fig:cors}
\end{figure}
Kuvassa \ref{fig:cors} käyttäjä navigoi osoitteeseen "palvelin1.fi", josta selain lataa HTML-dokumentin. Tässä dokumentissa on kaksi kuvaa, "kuva1.jpg" ja "kuva2.png". Näistä kuva 1 tulee samalta palvelimelta kuin mistä dokumenttikin, se on sallitty Same-origin policy -käytännön takia. Kuva 2 tulee toiselta palvelimelta. Selain estää sen lataamisen, koska palvelin 1 ei ole kertonut asiakkaan selaimelle, että osoitteesta "palvelin2.fi" voi ladata resursseja. Jos kuvan 2 lataaminen haluttaisiin toimivaksi,
Kuvassa \ref{fig:cors} käyttäjä navigoi osoitteeseen ''palvelin1.fi'', josta selain lataa HTML-dokumentin. Tässä dokumentissa on kaksi kuvaa, ''kuva1.jpg'' ja ''kuva2.png''. Kuva 1 tulee samalta palvelimelta kuin mistä dokumenttikin, joten selain sallii sen lataamisen SOP-käytännön mukaisesti. Kuva 2 taas tulee toiselta palvelimelta, joten selain estää sen lataamisen.
CORS:n asetusten määritys löytyy liitteestä \ref{appx:actix}.
Lähes kaikki nykyiset web-ohjelmistot kuitenkin vaativat näiden ulkoisten resurssien käyttöä. CORS on tekniikka, jossa palvelin kertoo selaimelle sallitut osoitteet, mistä resursseja saa noutaa.
Jotta kuvan 2 lataaminen saataisiin toimimaan, palvelimen tulee implementoida CORS-tekniikka. Palvelimen tulee lähettää asiakkaalle HTML-dokumentin yhteydessä ylätunniste [koodiesimerkki \ref{code:cors:header}], joka sisältää palvelimen 2 osoitteen. Näin käyttäjän selain tietää, että palvelin 1 sallii resurssien noutamisen palvelimelta 2.
\bigskip
\begin{code}
\inputminted{shell}{code/cors-header}
\captionof{listing}{Esimerkki CORS-ylätunnisteesta}
\label{code:cors:header}
\end{code}
CORS:n lisääminen tähän projektiin hoitui Actixin liitännäisellä actix\char`_cors. CORS:n asetusten määritys löytyy liitteestä \ref{appx:actix}.
\subsection{Tietokanta}
\label{project:database}
Tietokannaksi valikoitui itselleni tuttu MySQL. Relaatiotietokannan sai helposti yhdistettyä Rust-koodiini Diesel ORM:llä. Diesel on tähän mennessä käyttämistäni ORM-kirjastoista selkeästi mukavin käyttää.
\begin{figure}[h]
\centering
\includegraphics[width=12cm]{illustration/er-model.pdf}
\caption{Tietokannan ER-malli}
\label{fig:er-model}
\end{figure}
Käytännöllisimmät ominaisuudet kehittäjän näkökulmasta olivat Dieselin mukana tuleva komentorivikäyttöliittymä ja migraatiot. Jokaiselle taululle luodaan uusi migraatio, esimerkiksi \mintinline{shell}{diesel migration generate users}, jonka jälkeen Dieselin luomaan hakemistoon kirjoitetaan up.sql- ja down.sql-tiedostot, eli ohjeet siitä, miten tämä taulu luodaan ja poistetaan. Taulu viedään tietokantaan komennolla \mintinline{shell}{diesel migration run} ja taulun voi poistaa ja luoda uudelleen komennolla \mintinline{shell}{diesel migration redo}. Tämä mahdollistaa myös samalla sen, että versiohallintaan voi tallentaa useita versioita samasta taulusta ja palata helposti takaisin vanhempaan versioon, jos uudemman kanssa ilmenee ongelmia.
Tietokannaksi valikoitui itselleni tuttu MySQL. Koska projekti on vain yksinkertainen todennusdemo, tietokantaan tuli vain yksi taulu. Users-taulussa on käyttäjän tiedot: käyttäjänimi, salattu salasana, tieto käyttäjän ylläpitäjyydestä sekä käyttäjän luomisajankohta. Tietokannan ER-mallin näkee kuvasta \ref{fig:er-model}.
Relaatiotietokannan sai helposti yhdistettyä Rust-koodiini Diesel ORM:llä. Diesel on tähän mennessä käyttämistäni ORM-kirjastoista selkeästi mukavin käyttää.
Käytännöllisimmät ominaisuudet kehittäjän näkökulmasta olivat Dieselin mukana tuleva komentorivikäyttöliittymä ja migraatiot. Jokaiselle taululle luodaan uusi migraatio, esimerkiksi \mintinline{shell}{diesel migration generate users}, jonka jälkeen Dieselin luomaan hakemistoon kirjoitetaan up.sql- ja down.sql-tiedostot [liite \ref{appx:diesel}], eli ohjeet siitä, miten tämä taulu luodaan ja poistetaan. Taulu viedään tietokantaan komennolla \mintinline{shell}{diesel migration run} ja taulun voi poistaa ja luoda uudelleen komennolla \mintinline{shell}{diesel migration redo}. Tämä mahdollistaa myös samalla sen, että versiohallintaan voi tallentaa useita versioita samasta taulusta ja palata helposti takaisin vanhempaan versioon, jos uudemman kanssa ilmenee ongelmia.
\clearpage
Edellä mainitut työkalut helpottivat tietokannan kehitystä huomattavasti. Usein varsinkin projektin alkuvaiheilla tietokanta muuttuu jatkuvasti ja usein tulee tarve poistaa ja luoda tietokanta uudelleen. Monet kehittäjät pitävät juurikin tällaista Dieselin up.sql kaltaista tiedostoa versiohallinnassa ja tarpeen mukaan poistavat tietokannan käsin ja liittävät komennon tiedostosta tietokannan komentorivikäyttöliittymään. Dieseliä käytettäessä tämä tulee tehtyä automaattisesti ja se tuntuu todella luontevalta.
@ -134,6 +163,8 @@ WebAssembly-koodin suorittamiseksi selain tarvitsee pienen pätkän JavaScripti
\subsection{Kehys}
Asiakaspuolen sovelluskehykseksi valitsin Yew:n\cite{yew:home}. Yew muistuttaa hyvin paljon JavaScript-maailmassa suosittua Reactia, eli sen on komponenttipohjainen. Tämä tarkoittaa sitä, että kaikkien ohjelman osien, joilla halutaan näyttää jotakin käyttöliittymän osaa, täytyy implementoida Yew:n Component-rajapintaa. Tässä rajapinnassa on funktiot create, change, update ja view. Näiden funktioiden avulla Yew pystyy orkestroimaan kullakin hetkellä näytettävien komponenttien tilaa.
Tässä projektissa komponentteja oli kaksi: ohjelman juuri [liite \ref{appx:frontend-main}] ja kirjautumiskomponentti [liite \ref{appx:login}].
\subsection{Ulkonäkö}
\label{sect:ulkonäkö}
@ -160,7 +191,7 @@ Myös yew\char`_routerin kanssa oli omat haasteensa. Alkuun en saanut sitä toim
Asiakaspuolen reitityksen toteutuksen voi nähdä liitteessä \ref{appx:frontend-main}.
\section{Ongelmat}
Projektin loppuvaiheilla ilmeni muutamia ongelmia, jotka vaativat vielä jatkokehitystä.
Projektin loppuvaiheilla ilmeni muutamia ongelmia, joiden takia projekti vaatii vielä jatkokehitystä.
\subsection{Evästeet}
\label{sect:problems:cookies}
@ -175,7 +206,7 @@ Yhtenä ratkaisuna tähän ongelmaan olisi käyttää JSON Web Tokenin tallettam
Palvelimen ja tietokannan välisessä yhteydessä oli koko projektin ajan ongelma, että jokainen kysely tietokantaan kesti noin viisi sekuntia. Luulen että tämä ongelma liittyy jotenkin käyttämääni yhteyksien yhdistämiseen (luku \ref{project:database}), koska palvelimen loki näyttää satunnaisesti virheviestin \mintinline{shell}{Failed to create DB pool: Error(Some("Too many connections")}. Asian selvittäminen jää jatkokehitykseen.
\section{Tulokset}
Tuloksena syntyi yksinkertainen web-ohjelma, jossa on toimiva sisäänkirjautumistoiminallisuus, jonka avulla palvelimelta asiakas voi noutaa suojattua dataa. Projektissa sekä palvelin- että asiakaspuoli on toteutettu Rustilla. Kuvassa \ref{fig:login-process} on määritelty kaikki kirjautumisprosessin vaiheet.
Tuloksena syntyi yksinkertainen web-ohjelma, jossa on toimiva sisäänkirjautumistoiminallisuus. Sen avulla asiakas voi noutaa palvelimelta suojattua dataa. Kuvassa \ref{fig:login-process} on määritelty kaikki kirjautumisprosessin vaiheet.
\begin{figure}[h]
\centering

View file

@ -14,6 +14,6 @@ Vahvan tyypityksen hyötyjä ei voi kieltää, mutta kuten luvussa \ref{sect:sov
Kirjastojen saatavuus on ongelma asiakaspuolella. Kaikkien kirjastojen, jotka vuorovaikuttavat selaimen kanssa, pitää nimenomaan tukea WebAssemblya. WebAssembly-ekosysteemi on vielä melko alkutekijöissään, ja näitä kirjastoja on vielä hyvin vähän. Tämän projektin aikana tätä ei ilmennyt muuta kuin tyylimäärityksissä (luku \ref{sect:ulkonäkö}), mutta tämän projektin käyttöliittymä oli vielä todella yksinkertainen, eikä montaa kirjastoa tarvittukaan.
Jos lähdetään siitä oletuksesta, että suurin osa web-kehittäjistä osaa jo JavaScriptiä, en näiden syiden takia voi suositella kokonaan uuden kielen opettelemista asiakaspuolta varten. Mutta jos on esimerkiksi kehittäjä, jolla ei ole mitään taustaa web-kehityksessä, mutta osaa jo valmiiksi Rustia, tai muita matalemman tason kieliä, Rust voi olla mielekäs vaihtoehto. Tässäkin tapauksessa edellytyksenä on, että kaikki kehittäjän tarvitsemat kirjastot ovat saatavilla, tai kehittäjällä on aikaa ja halua toteuttaa puuttuvien kirjastojen toiminallisuus itse.
Jos lähdetään siitä oletuksesta, että suurin osa web-kehittäjistä osaa jo JavaScriptiä, en näiden syiden takia voi suositella kokonaan uuden kielen opettelemista asiakaspuolta varten. Mutta jos on esimerkiksi kehittäjä, jolla ei ole mitään taustaa web-kehityksessä, mutta osaa jo valmiiksi Rustia, tai muita matalan tason kieliä, Rust voi olla mielekäs vaihtoehto. Tässäkin tapauksessa edellytyksenä on, että kaikki kehittäjän tarvitsemat kirjastot ovat saatavilla, tai kehittäjällä on aikaa ja halua toteuttaa puuttuvien kirjastojen toiminallisuus itse.
Rust-koodista käännettyjä WebAssembly-tiedostoja voi myös sisällyttää JavaScript-ohjelmiin \cite{javascript-wa}. Jos asiakaspuolen ohjelmassa on osia, jotka vaativat suoritustehoa ja/tai rinnakkaisajo-ominaisuuksia, voi olla hyvä vaihtoehto kirjoittaa vain nämä osat Rustilla ja sisällyttää ne JavaScript-koodiin.

1
tex/code/cors-header Normal file
View file

@ -0,0 +1 @@
Access-Control-Allow-Origin: http://palvelin2.fi

1
tex/code/down.sql Normal file
View file

@ -0,0 +1 @@
DROP TABLE users;

8
tex/code/up.sql Normal file
View file

@ -0,0 +1,8 @@
CREATE TABLE users (
`id` int NOT NULL AUTO_INCREMENT,
`username` varchar(100) UNIQUE NOT NULL,
`password` varchar(128) NOT NULL,
`admin` boolean NOT NULL,
`created_at` timestamp NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

View file

@ -0,0 +1 @@
<mxfile host="app.diagrams.net" modified="2020-05-09T17:38:01.914Z" agent="5.0 (X11)" etag="Pmiw6ZXeZeuwz4isxrYX" version="13.0.9" type="device"><diagram id="_RAwPwxGb8NAfqn0KXI3" name="Page-1">7VjbcpswEP0aPyaDQGD7sXHS27TTdNKZNk8dGRZbYxk5sohxv77CiIuQXV9K4vTywmgPq0V79mgR9LzRPHsjyGL6kUfAeq4TZT3vuue6w4G65Pa6sJGLCmAiaKShGrijP0CDjkZTGsHScJScM0kXJhjyJIFQGhgRgq9Mt5gz86kLMgELuAsJs9GvNJLTAh34To2/BTqZlk9Gjr4zJ6WzBpZTEvFVA/Juet5IcC6L0TwbAcupK3kp5r3ecbdamIBEHjJhfbUiM/yeUkzTizTLHj5/f7jQUR4JS3XC7xIJIgGpFy3XJRMqmiJdGVcqk0UOhoynKvjVakol3C1ImIMrpQKFTeWcKQupYUwZG3HGxSaOF/kwiHAeRgo+g8adgTv2gkDd0YsCISHbmS2qOFTSAz4HKdbKRU/wStor3Wl7VVcReX6BTRsVHGo/ooUzqULX3KqBpvcIql2L6i8UJJ+RRBKL7IriNaNJBGI/y2OeKsfow7gCSDibiBz9lEoVBXaUg8AgDreVIwgHMI67KUeAzXIM7WqUULMYVdU6rwayy3EPK6sOomBVU3ec0OM4dsOtzEbBOPA7EjoamsxWnbMpdLSF2+DJqPV2NpWLJTBCk7+A5v7ZWcYWy69CSbNOuX2e5oBfHLe+xe0tYY/AOpbueeh9AR2ib/FrHzeS6FV+ftucM8hySQueiJA23GAYMiq/qbFz6WvrPrf0+DprGuvSSFRSjUm5eV/Gy4162sYq5xVrhsg6QbYqo/LiqQjhAMWp/CYg9257u9aNWvpbSlliQvVfSR/NBW+rr37CLacqlUpKPsaXvikmpyWSIlU9r3kctUKZgRBuBSqosAJtBFcl/hsaHPxTGjyXYlxbMehExdihkPfMmhk+uWZQUzGVfvZrxhCNczn09+hmY92CoIqT/POi84bmHtrQzqlO7JivRtw/UZvYbwVqf7jsUKbSBFk33Ba5w3L3gr0hNjcTNj761aCI2Knsy1yetFViQ/jo18JXRlu79WYwd8K+jdCl5v+Id7jXbzVRxz9R864ZyG/F6Uryfdxa73NI3v4x1pnkdwi1v69jn/CG6FLch55Q3f8N/Qh1B63/lK2Gvt8fHeeP9G46cfcos/5jXbjXf/29m58=</diagram></mxfile>

Binary file not shown.

Binary file not shown.

View file

@ -82,6 +82,10 @@
\addtocontents{toc}{\vspace{11pt}}
\liite{4}
\input{appendix/login.tex}
\addtocontents{toc}{\vspace{11pt}}
\liite{5}
\input{appendix/diesel.tex}
%%%%%%%%%%
\end{document}