Mitä rakennamme
Vieraskirja: lomake Reactissa lähettää viestin palvelimellesi, palvelin tallentaa sen ja näyttää jokaiselle tulevalle vierailijalle. Muistatko tason 2 lomakkeen jolla ei ollut minne lähettää? Tänään maksetaan se velka.
Näytän sinulle: vieraskirjan backend
my-server-kansiossa asenna ensin yksi paketti lisää:
npm install cors
Ja muokkaa server.js:ää:
const express = require("express");
const cors = require("cors");
const app = express();
app.use(cors()); // allow the frontend on a different port to ask questions
app.use(express.json()); // understand JSON in incoming requests
const messages = [
{ name: "Martin", text: "First message! Long live the guestbook. 📖" },
];
// GET – hand out messages
app.get("/api/messages", (request, response) => {
response.json(messages);
});
// POST – accept a new message
app.post("/api/messages", (request, response) => {
const { name, text } = request.body;
// Never trust input: check it on the server too!
if (!name || !text || name.length > 50 || text.length > 500) {
return response.status(400).json({ error: "Invalid message." });
}
messages.push({ name, text });
response.json({ saved: true });
});
app.listen(3900, () => {
console.log("Server running at http://localhost:3900");
});
Uutta:
cors()– frontend pyörii portissa 3901, palvelin 3900:ssa. Selaimet normaalisti estävät tällaiset “eri alkuperän” pyynnöt (turvallisuussääntö nimeltä CORS); näin sallit sen palvelimella.app.post(...)– ensimmäinen POST-endpointisi! Lomakedata näkyyrequest.body:ssä.- Tarkistus palvelimella – frontend tarkistaa jo lomakkeen, mutta hyökkääjä voi ohittaa lomakkeen ja lähettää pyynnön suoraan. Siksi rautainen sääntö: backend tarkistaa aina, eikä koskaan luota frontendiin.
status(400)tarkoittaa “huono pyyntö.”
Näytän sinulle: vieraskirjan frontend
React-projektissasi luo src/GuestBook.jsx:
import { useState, useEffect } from 'react';
function GuestBook() {
const [messages, setMessages] = useState([]);
const [name, setName] = useState("");
const [text, setText] = useState("");
// On first render: download the messages from the server
useEffect(() => {
fetch("http://localhost:3900/api/messages")
.then((response) => response.json())
.then((data) => setMessages(data));
}, []);
function submit(event) {
event.preventDefault();
fetch("http://localhost:3900/api/messages", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name, text }),
})
.then((response) => response.json())
.then(() => {
setMessages([...messages, { name, text }]); // add it to the screen too
setName("");
setText("");
});
}
return (
<div>
<h2>Guestbook 📖</h2>
{messages.map((message, index) => (
<div className="card" key={index}>
<strong>{message.name}</strong>
<p>{message.text}</p>
</div>
))}
<form onSubmit={submit}>
<input
value={name}
onChange={(event) => setName(event.target.value)}
placeholder="Your name"
/>
<textarea
value={text}
onChange={(event) => setText(event.target.value)}
placeholder="Write a message..."
/>
<button type="submit">Send</button>
</form>
</div>
);
}
export default GuestBook;
Kolme viimeistä uutta asiaa Reactissa:
useEffect(() => {...}, [])– “aja tämä kerran, kun komponentti ensin näkyy.” Ihanteellinen paikka ladata data.fetchmethod: "POST":lla – lähetämme dataa;JSON.stringifypakkaa sen JSON:iksi.- Yhdistetyt lomakkeet – kenttä lukee arvonsa tilasta (
value={name}) ja kirjoittaa sen takaisin kirjoittaessa (onChange). Lomake ja tila pysyvät aina synkassa.
Nyt sinun vuorosi 💪
- Saa molemmat käyntiin: palvelin yhdessä terminaalissa (
node server.js), React toisessa (npm run dev -- --port 3901). Kaksi terminaalia, kaksi ohjelmaa – tervetuloa full-stackiin! - Lisää
<GuestBook />sovellukseesi ja kokeile: kirjoita viesti, lataa sivu uudelleen – viesti on edelleen siellä (niin kauan kuin palvelin pyörii). - Mukauta vieraskirja projektiisi: 🏫 viestit koululle · 🙋 viestitaulu ystäville · 🌍 “minne pitäisi mennä?” -vinkit vierailijoilta · ⚽ laulut faneilta.
- Kokeile lähettää tyhjä viesti – frontend päästää sen läpi (siinä ei ole tarkistusta), mutta palvelin hylkää sen. Lisää sitten tarkistus frontendiin, jotta lomake on yhtä kohtelias kuin tasolla 2.
Viestit katoavat kun palvelin käynnistyy uudelleen – ne elävät vain taulukossa muistissa. Oikeat sovellukset tallentavat ne tietokantaan, joka selviää kaikesta. Se on ensimmäinen asia opittavaksi kun tämä taso on valmis – avainsanat: SQLite, PostgreSQL.
Tarkista itse: Lomakkeen viesti matkustaa palvelimelle, tallentuu ja tulee takaisin sivun uudelleenlatauksen jälkeen. Rakensit juuri full-stack-sovelluksen – frontend, backend, API. Juuri sitä ammattikehittäjät tekevät joka päivä.
Mitä opit tästä oppitunnista
useEffect(..., [])lataa datan ensimmäisellä renderöinnillä;fetchPOST:lla lähettää sen.- Turvallisuuden rautinen sääntö: palvelin tarkistaa jokaisen syötteen, vaikka frontend tarkistaisikin.
- Full-stack = kaksi käynnissä olevaa ohjelmaa (3901 + 3900) jotka puhuvat keskenään API:n kautta.
© 2026 Ing. Martin Polak / AlgoRhino · Sisällön käyttöehdot