Skip to content

Commit 23a8abd

Browse files
committed
Merge branch 'source' into part4-spanish
2 parents bbf5b6a + 25e7f16 commit 23a8abd

File tree

14 files changed

+31
-77
lines changed

14 files changed

+31
-77
lines changed

src/content/0/fi/osa0b.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ Ennen AJAX:in aikakautta jokainen sivu toimi aiemmassa luvussa olevan [perinteis
479479
480480
Muistiinpanojen sivu siis lataa näytettävän datan AJAX:illa. Lomakkeen lähetys sen sijaan tapahtuu perinteisen web-lomakkeen lähetysmekanismin kautta.
481481
482-
Sovelluksen urlit heijastavat vanhaa, huoletonta aikaa. JSON-muotoinen data haetaan urlista <https://studies.cs.helsinki.fi/exampleapp/data.json>, ja uuden muistiinpanon tiedot lähetetään urliin <https://studies.cs.helsinki.fi/exampleapp/new_note>. Nykyään näin valittuja urleja ei pidetä ollenkaan hyvinä – ne eivät noudata ns. [RESTful](https://en.wikipedia.org/wiki/Representational_state_transfer#Applied_to_Web_services)-apien yleisesti hyväksyttyjä konventioita. Käsittelemme asiaa tarkemmin [osassa 3](/osa3).
482+
Sovelluksen urlit heijastavat vanhaa, huoletonta aikaa. JSON-muotoinen data haetaan urlista <https://studies.cs.helsinki.fi/exampleapp/data.json>, ja uuden muistiinpanon tiedot lähetetään urliin <https://studies.cs.helsinki.fi/exampleapp/new_note>. Nykyään näin valittuja urleja ei pidetä ollenkaan hyvinä – ne eivät noudata ns. [RESTful](https://en.wikipedia.org/wiki/REST#Applied_to_web_services)-apien yleisesti hyväksyttyjä konventioita. Käsittelemme asiaa tarkemmin [osassa 3](/osa3).
483483
484484
AJAXiksi kutsuttu asia on arkipäiväistynyt ja muuttunut itsestäänselvyydeksi. Koko termi on hiipunut unholaan, ja nuori polvi ei ole sitä edes ikinä kuullut.
485485
@@ -521,7 +521,7 @@ Pyyntöön liitetty headeri <i>Content-Type</i> kertoo palvelimelle, että pyynn
521521
522522
Ilman headeria palvelin ei osaisi parsia pyynnön mukana tulevaa dataa oikein.
523523
524-
Palvelin vastaa kyselyyn statuskoodilla [201 created](https://httpstatuses.com/201). Tällä kertaa palvelin ei pyydä uudelleenohjausta kuten aiemmassa versiossamme. Selain pysyy samalla sivulla, ja muita HTTP-pyyntöjä ei suoriteta.
524+
Palvelin vastaa kyselyyn statuskoodilla [201 created](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/201). Tällä kertaa palvelin ei pyydä uudelleenohjausta kuten aiemmassa versiossamme. Selain pysyy samalla sivulla, ja muita HTTP-pyyntöjä ei suoriteta.
525525
526526
Ohjelman Single Page App ‑versiossa lomakkeen tietoja ei lähetetä selaimen normaalin lomakkeiden lähetysmekanismin avulla. Lähettämisen hoitaa selaimen lataamassa JavaScript-tiedostossa määritelty koodi. Katsotaan hieman koodia, vaikka yksityiskohdista ei tarvitse nytkään välittää liikaa.
527527
@@ -585,7 +585,7 @@ Reactin asema näyttää tällä hetkellä vahvalta, mutta JavaScript-maailma ei
585585
586586
Mitä tarkoitetaan kurssin nimellä <i>Full stack ‑web-sovelluskehitys</i>? Full stack on hypenomainen termi – kaikki puhuvat siitä, mutta kukaan ei oikein tiedä, mitä se tarkoittaa, tai ainakaan mitään yhteneväistä määritelmää termille ei ole.
587587
588-
Käytännössä kaikki web-sovellukset sisältävät (ainakin) kaksi "kerrosta" ylempänä eli lähempänä loppukäyttäjää olevan selaimen ja alla olevan palvelimen. Palvelimen alapuolella on usein vielä tietokanta. Näin websovelluksen <i>arkkitehtuurin</i> voi ajatella muodostavan pinon, englanniksi <i>stack</i>.
588+
Käytännössä kaikki web-sovellukset sisältävät (ainakin) kaksi "kerrosta". Ylin kerros on lähempänä loppukäyttäjää oleva selain, joka suorittaa JavaScript-koodin ja renderöi sovelluksen HTML:n. Alempi kerros taas on sivuston tiedostot sisältämä palvelin. Palvelimen alapuolella on usein vielä tietokanta. Näin websovelluksen <i>arkkitehtuurin</i> voi ajatella muodostavan pinon, englanniksi <i>stack</i>.
589589
590590
Web-sovelluskehityksen yhteydessä puhutaan usein myös "frontista" ([frontend](https://en.wikipedia.org/wiki/Front_and_back_ends)) ja "backistä" ([backend](https://en.wikipedia.org/wiki/Front_and_back_ends)). Selain on frontend, ja selaimessa suoritettava JavaScript on frontend-koodia. Palvelimella taas pyörii backend-koodi.
591591

src/content/13/en/part13a.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -594,17 +594,17 @@ app.post('/api/notes', async (req, res) => {
594594

595595
<div class="tasks">
596596

597-
### Tasks 13.1.-13.3.
597+
### Exercises 13.1.-13.3.
598598

599599
In the tasks of this section, we will build a blog application backend similar to the tasks in [section 4](/en/part4), which should be compatible with the frontend in [section 5](/en/part5) except for error handling. We will also add various features to the backend that the frontend in section 5 will not know how to use.
600600

601-
#### Task 13.1.
601+
#### Exercise 13.1.
602602

603603
Create a GitHub repository for the application and create a new Fly.io or Heroku application for it, as well as a Postgres database. As mentioned [here](/en/part13/using_relational_databases_with_sequelize#application-database) you might set up your database also somewhere else, and in that case the Fly.io of Heroku app is not needed.
604604

605605
Make sure you are able to establish a connection to the application database.
606606

607-
#### Task 13.2.
607+
#### Exercise 13.2.
608608

609609
On the command-line, create a <i>blogs</i> table for the application with the following columns:
610610
- id (unique, incrementing id)
@@ -846,9 +846,9 @@ The print looks like the following:
846846

847847
<div class="tasks">
848848

849-
### Task 13.4.
849+
### Exercise 13.4.
850850

851-
#### Task 13.4.
851+
#### Exercise 13.4.
852852

853853
Transform your application into a web application that supports the following operations
854854

src/content/13/en/part13b.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -231,13 +231,13 @@ The current code for the application is in its entirety on [GitHub](https://gith
231231

232232
<div class="tasks">
233233

234-
### Tasks 13.5.-13.7.
234+
### Exercises 13.5.-13.7.
235235

236-
#### Task 13.5.
236+
#### Exercise 13.5.
237237

238238
Change the structure of your application to match the example above, or to follow some other similar clear convention.
239239

240-
#### Task 13.6.
240+
#### Exercise 13.6.
241241

242242
Also, implement support for changing the number of a blog's likes in the application, i.e. the operation
243243

@@ -251,7 +251,7 @@ The updated number of likes will be relayed with the request:
251251
}
252252
```
253253

254-
#### Task 13.7.
254+
#### Exercise 13.7.
255255

256256
Centralize the application error handling in middleware as in [part 3](/en/part3/saving_data_to_mongo_db#moving-error-handling-into-middleware). You can also enable middleware [express-async-errors](https://github.com/davidbanham/express-async-errors) as we did in [part 4](/en/part4/testing_the_backend#eliminating-the-try-catch).
257257

@@ -693,9 +693,9 @@ Instead we can achieve the same with this. Using one of the two methods is neces
693693

694694
<div class="tasks">
695695

696-
### Tasks 13.8.-13.12.
696+
### Exercises 13.8.-13.12.
697697

698-
#### Task 13.8.
698+
#### Exercise 13.8.
699699

700700
Add support for users to the application. In addition to ID, users have the following fields:
701701

@@ -738,7 +738,7 @@ Expand the application so that the current logged-in user identified by a token
738738

739739
Make deletion of a blog only possible for the user who added the blog.
740740

741-
#### Task 13.12.
741+
#### Exercise 13.12.
742742

743743
Modify the routes for retrieving all blogs and all users so that each blog shows the user who added it and each user shows the blogs they have added.
744744

@@ -963,9 +963,9 @@ The current code for the application is in its entirety on [GitHub](https://gith
963963

964964
<div class="tasks">
965965

966-
### Tasks 13.13.-13.16
966+
### Exercises 13.13.-13.16
967967

968-
#### Task 13.13.
968+
#### Exercise 13.13.
969969

970970
Implement filtering by keyword in the application for the route returning all blogs. The filtering should work as follows
971971
- _GET /api/blogs?search=react_ returns all blogs with the search word <i>react</i> in the <i>title</i> field, the search word is case-insensitive
@@ -982,7 +982,7 @@ _GET /api/blogs?search=jami_ returns blogs with the search word <i>jami</i> in t
982982

983983
Modify the blogs route so that it returns blogs based on likes in descending order. Search the [documentation](https://sequelize.org/master/manual/model-querying-basics.html) for instructions on ordering,
984984

985-
#### Task 13.16.
985+
#### Exercise 13.16.
986986

987987
Make a route for the application _/api/authors_ that returns the number of blogs for each author and the total number of likes. Implement the operation directly at the database level. You will most likely need the [group by](https://sequelize.org/master/manual/model-querying-basics.html#grouping) functionality, and the [sequelize.fn](https://sequelize.org/master/manual/model-querying-basics.html#specifying-attributes-for-select-queries) aggregator function.
988988

src/content/2/fi/osa2e.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ const App = () => {
318318
}
319319
```
320320

321-
Tämä on onkin luonnollinen tapa alustaa tila, muistiinpanot muodostavat joukon, joten tyhjä taulukko on luonteva alkuarvo muuttujalle.
321+
Tämä onkin luonnollinen tapa alustaa tila, muistiinpanot muodostavat joukon, joten tyhjä taulukko on luonteva alkuarvo muuttujalle.
322322

323323
Niissä tilanteissa, missä tilaan talletetaan "yksi asia" tilan luonteva alkuarvo on usein _null_, joka kertoo että tilassa ei ole vielä mitään. Kokeillaan miten käy jos alustamme nyt tilan nulliksi:
324324

@@ -621,6 +621,8 @@ const api_key = import.meta.env.VITE_SOME_KEY
621621
// muuttujassa api_key on nyt käynnistyksessä annettu API-avaimen arvo
622622
```
623623
624+
Huomaa, että ympäristömuuttujan nimen täytyy alkaa merkkijonolla _VITE\__.
625+
624626
Tämä oli osan viimeinen tehtävä ja on aika sekä puskea koodi GitHubiin että merkitä tehdyt tehtävät [palautussovellukseen](https://studies.cs.helsinki.fi/stats/courses/fullstackopen).
625627
626628
</div>

src/content/3/en/part3a.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ In this part, our focus shifts towards the backend: that is, towards implementin
1111

1212
We will be building our backend on top of [NodeJS](https://nodejs.org/en/), which is a JavaScript runtime based on Google's [Chrome V8](https://developers.google.com/v8/) JavaScript engine.
1313

14-
This course material was written with version <i>v18.13.0</i> of Node.js. Please make sure that your version of Node is at least as new as the version used in the material (you can check the version by running _node -v_ in the command line).
14+
This course material was written with version <i>v20.11.0</i> of Node.js. Please make sure that your version of Node is at least as new as the version used in the material (you can check the version by running _node -v_ in the command line).
1515

1616
As mentioned in [part 1](/en/part1/java_script), browsers don't yet support the newest features of JavaScript, and that is why the code running in the browser must be <i>transpiled</i> with e.g. [babel](https://babeljs.io/). The situation with JavaScript running in the backend is different. The newest version of Node supports a large majority of the latest features of JavaScript, so we can use the latest features without having to transpile our code.
1717

@@ -154,7 +154,7 @@ import http from 'http'
154154

155155
These days, code that runs in the browser uses ES6 modules. Modules are defined with an [export](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export) and taken into use with an [import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import).
156156

157-
However, Node.js uses so-called [CommonJS](https://en.wikipedia.org/wiki/CommonJS) modules. The reason for this is that the Node ecosystem had a need for modules long before JavaScript supported them in the language specification. Node supports now also the use of ES6 modules, but since the support is [not quite perfect](https://nodejs.org/api/esm.html#modules-ecmascript-modules) yet, we'll stick to CommonJS modules.
157+
However, Node.js uses so-called [CommonJS](https://en.wikipedia.org/wiki/CommonJS) modules. The reason for this is that the Node ecosystem needed modules long before JavaScript supported them in the language specification. Node supports now also the use of ES6 modules, but since the support is not quite perfect yet, we'll stick to CommonJS modules.
158158

159159
CommonJS modules function almost exactly like ES6 modules, at least as far as our needs in this course are concerned.
160160

src/content/3/en/part3b.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ host: example.com
4444
port: 80
4545
```
4646

47-
When you visit a website (e.g. <http://catwebsites.com>), the browser issues a request to the server on which the website (catwebsites.com) is hosted. The response sent by the server is an HTML file that may contain one or more references to external assets/resources hosted either on the same server that <i>catwebsites.com</i> is hosted on or a different website. When the browser sees reference(s) to a URL in the source HTML, it issues a request. If the request is issued using the URL that the source HTML was fetched from, then the browser processes the response without any issues. However, if the resource is fetched using a URL that doesn't share the same origin(scheme, host, port) as the source HTML, the browser will have to check the _Access-Control-Allow-origin_ response header. If it contains _*_ or the URL of the source HTML, the browser will process the response, otherwise the browser will refuse to process it and throws an error.
47+
When you visit a website (e.g. <http://catwebsites.com>), the browser issues a request to the server on which the website (catwebsites.com) is hosted. The response sent by the server is an HTML file that may contain one or more references to external assets/resources hosted either on the same server that <i>catwebsites.com</i> is hosted on or a different website. When the browser sees reference(s) to a URL in the source HTML, it issues a request. If the request is issued using the URL that the source HTML was fetched from, then the browser processes the response without any issues. However, if the resource is fetched using a URL that doesn't share the same origin(scheme, host, port) as the source HTML, the browser will have to check the _Access-Control-Allow-origin_ response header. If it contains _*_ on the URL of the source HTML, the browser will process the response, otherwise the browser will refuse to process it and throws an error.
4848

4949
The <strong>same-origin policy</strong> is a security mechanism implemented by browsers in order to prevent session hijacking among other security vulnerabilities.
5050

src/content/3/fi/osa3a.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ Siirrämme tässä osassa fokuksen backendiin eli palvelimella olevaan toiminnal
1111

1212
Backendin toteutusympäristönä käytämme [Node.js](https://nodejs.org/en/):ää, joka on melkein missä vaan, erityisesti palvelimilla ja omalla koneellasikin toimiva Googlen [V8](https://developers.google.com/v8/)-JavaScript-moottoriin perustuva JavaScriptin suoritusympäristö.
1313

14-
Kurssimateriaalia tehtäessä on ollut käytössä Node.js:n versio <i>v18.13.02</i>. Suosittelen, että omasi on vähintään yhtä tuore (ks. komentoriviltä _node -v_).
14+
Kurssimateriaalia tehtäessä on ollut käytössä Node.js:n versio <i>v20.11.0</i>. Suosittelen, että omasi on vähintään yhtä tuore (ks. komentoriviltä _node -v_).
1515

1616
Kuten [osassa 1](/osa1/java_scriptia) todettiin, selaimet eivät vielä osaa kaikkia uusimpia JavaScriptin ominaisuuksia, ja siksi selainpuolen koodi täytyy kääntää eli <i>transpiloida</i> esim [Babel](https://babeljs.io/):illa. Backendissa tilanne on kuitenkin toinen, koska uusin Node hallitsee riittävissä määrin myös JavaScriptin uusia versioita, joten suoritamme Nodella kirjoittamaamme koodia suoraan ilman transpilointivaihetta.
1717

1818
Tavoitteenamme on tehdä [osan 2](/osa2) muistiinpanosovellukseen sopiva backend. Aloitetaan kuitenkin ensin perusteiden läpikäyminen toteuttamalla perinteinen "hello world" ‑sovellus.
1919

20-
**Huomaa**, että tässä osassa ja sen tehtävissä luotavat sovellukset eivät ole Reactia, eli emme käytä <i>create-react-app</i>-sovellusta tämän osan sovellusten rungon alustamiseen.
20+
**Huomaa**, että tässä osassa ja sen tehtävissä luotavat sovellukset eivät ole Reactia, eli emme käytä xwviteä tämän osan sovellusten rungon alustamiseen.
2121

2222
Osassa 2 oli jo puhe [npm](/osa2/palvelimella_olevan_datan_hakeminen#npm):stä, eli JavaScript-projektien hallintaan liittyvästä, alun perin Node-ekosysteemistä kotoisin olevasta työkalusta.
2323

@@ -150,9 +150,9 @@ ottaa käyttöön Noden sisäänrakennetun [web-palvelimen](https://nodejs.org/d
150150
import http from 'http'
151151
```
152152

153-
Selaimen puolella käytetään (nykyään) ES6:n moduuleita, eli moduulit määritellään [exportilla](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export) ja otetaan käyttöön [importilla](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import).
153+
Selaimen puolella käytetään nykyään ES6:n moduuleita, eli moduulit määritellään [exportilla](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export) ja otetaan käyttöön [importilla](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import).
154154

155-
Node.js kuitenkin käyttää ns. [CommonJS](https://en.wikipedia.org/wiki/CommonJS)-moduuleja. Syy tälle on siinä, että Node-ekosysteemillä oli tarve moduuleihin jo kauan ennen kuin JavaScript tuki moduuleja kielen tasolla. Node tukee myös ES-moduuleja, mutta koska tuki ei ole vielä kaikilta osin [täydellinen](https://nodejs.org/api/esm.html#modules-ecmascript-modules), pitäydymme CommonJS-moduuleissa.
155+
Node.js kuitenkin käyttää ns. [CommonJS](https://en.wikipedia.org/wiki/CommonJS)-moduuleja. Syy tälle on siinä, että Node-ekosysteemillä oli tarve moduuleihin jo kauan ennen kuin JavaScript tuki moduuleja kielen tasolla. Node tukee myös ES-moduuleja, mutta koska tuki ei ole vielä kaikilta osin täydellinen, pitäydymme CommonJS-moduuleissa.
156156

157157
CommonJS-moduulit toimivat melko samaan tapaan kuin ES6-moduulit, ainakin tämän kurssin tarpeiden puitteissa.
158158

src/content/4/en/part4a.md

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -407,14 +407,6 @@ The nature of VS Code bleeding into how you write your code is probably not idea
407407
408408
In the exercises for this part, we will be building a <i>blog list application</i>, that allows users to save information about interesting blogs they have stumbled across on the internet. For each listed blog we will save the author, title, URL, and amount of upvotes from users of the application.
409409
410-
**Note:** You should install Mongoose version 7.6.5 with the command:
411-
412-
```bash
413-
npm install mongoose@7.6.5
414-
```
415-
416-
since the most recent Mongoose version does not support a library that we will be using in a later part of the course!
417-
418410
#### 4.1 Blog List, step 1
419411
420412
Let's imagine a situation, where you receive an email that contains the following application body and instructions:

src/content/4/fi/osa4a.md

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -397,15 +397,6 @@ Eli eksportoitava asia (tässä tilanteessa router-olio) sijoitetaan muuttujaan
397397
398398
Rakennamme tämän osan tehtävissä <i>blogilistasovellusta</i>, jonka avulla käyttäjien on mahdollista tallettaa tietoja Internetistä löytämistään mielenkiintoisista blogeista. Kustakin blogista talletetaan sen kirjoittaja (author), aihe (title), url sekä blogilistasovelluksen käyttäjien antamien äänien määrä.
399399
400-
**HUOM** Asenna Mongoosesta versio 7.6.5 komennolla
401-
402-
```bash
403-
npm install mongoose@7.6.5
404-
```
405-
406-
Joudumme käyttämään hieman vanhempaa versiota, sillä uusin Mongoose-versio ei tue kirjastoa, jota tulemme käyttämään kurssin myöhemmässä osassa!
407-
408-
409400
#### 4.1 blogilista, step1
410401
411402
Kuvitellaan tilanne, jossa saat sähköpostitse seuraavan, yhteen tiedostoon koodatun sovellusrungon:

src/content/4/fi/osa4c.md

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -380,16 +380,6 @@ userSchema.plugin(uniqueValidator) // highlight-line
380380
// ...
381381
```
382382

383-
Huom: asentaessasi kirjastoa _mongoose-unique-validator_ saatat törmätä seuraavaan virheilmoitukseen:
384-
385-
![](../../images/4/uniq.png)
386-
387-
Syynä tälle on se, että kirjasto ei ole kirjoitushetkellä (10.11.2023) vielä yhteensopiva Mongoosen version 8 kanssa. Jos törmäät virheeseen, voit ottaa käyttöösi Mongoosen vanhemman version suorittamalla komennon
388-
389-
```
390-
npm install [email protected]
391-
```
392-
393383
Voisimme toteuttaa käyttäjien luomisen yhteyteen myös muita tarkistuksia, esim. onko käyttäjätunnus tarpeeksi pitkä, koostuuko se sallituista merkeistä ja onko salasana tarpeeksi hyvä. Jätämme ne kuitenkin vapaaehtoiseksi harjoitustehtäväksi.
394384

395385
Ennen kuin menemme eteenpäin, lisätään sovellukseen alustava versio kaikki käyttäjät palauttavasta käsittelijäfunktiosta:

0 commit comments

Comments
 (0)