Lektion 17 — Øvelser
Man lærer et repository bedst ved at flytte sin egen route over på det og se listen huske. Detaljerne, der ikke står på slidesne, står her.
Hvis du ikke nåede forberedelsen, så kør hent.js mod din
egen database først. Det tager 15 minutter, og så ved du, at forbindelsen
virker, før du rører server.js.
| Øvelse | Hvornår | Tid |
|---|---|---|
| 1 Listen husker | Efter quizzen om repository og GET |
~35 min |
2 POST og testskemaet |
Efter quizzen om POST |
~30 min |
| 3 Gruppens handling | Efter øvelse 2 | ~30 min |
Alle i gruppen laver øvelserne på egen maskine, mod gruppens database fra
lektion 15. Når én opretter en patient, ser alle den — og en CPR, som én har
oprettet, kan de andre ikke oprette igen. Brug derfor hver jeres egen
syntetiske CPR, når I tester POST. Én i gruppen committer gruppens version.
De andre puller og laver deres egen .env.
Øvelse 1 — Listen husker
Mål: GET /api/patients i gruppens server.js henter fra tabellen i
Neon. Mockuppets tabel viser de fem testpatienter, også efter en genstart.
Arbejd i gruppens projekt, i mappen med server.js fra lektion 13.
Det skal du lave
- Installér
pg:
npm install pg
- Lav
.envved siden afserver.jsmed gruppens connection-string fra lektion 15, øvelse 3. Retsslmode=requiretilsslmode=verify-full.
DATABASE_URL=postgresql://neondb_owner:…@…neon.tech/neondb?sslmode=verify-full&channel_binding=require
- Tilføj
.envi.gitignore, ved siden afnode_modules/. Kørgit status..envmå ikke stå på listen. - Lav
patients.jsved siden afserver.js, som på slidesne:Pool,pool.on("error", …)oghentPatienter(). Eksportér den medmodule.exports. - I
server.js:- slet arrayet
patients. Har IGET /api/patients/:cprfra lektion 13, skal den kaldehentPatient(cpr)(ekstra-opgaven nedenfor) eller tages ud, indtil den gør det. Ellers læser den et array, der ikke findes. - slet den gamle
POST-route medpatients.push— I skriver den igen i øvelse 2 require("./patients")øverst- gør
GET /api/patientsasync, kaldhentPatienter(), og svar500med{ error: "serverfejl" }icatch
- slet arrayet
- Start serveren:
node --env-file=.env server.js
- Åbn
http://localhost:3000/api/patientsi browseren. Du skal se de fem testpatienter fra Neon. - Åbn mockuppet lokalt. Tabellen skal vise de samme fem uden at
fetcher ændret. - Stop serveren med Ctrl+C, og start den igen. Hent igen. Patienterne er der stadig.
- Ejeren af databasen indsætter en patient i Neons SQL-editor. Genindlæs mockuppet hos en anden i gruppen. Den nye patient står i tabellen.
Tjekliste
-
git statusviser ikke.env -
server.jshar ikke længere etpatients-array -
server.jsindeholder ingen SQL. Al SQL står ipatients.js - Tabellen i mockuppet viser data fra Neon
- Genstart af serveren ændrer ikke listen
Øvelsen er i hus, når en anden i gruppen kan pege på, hvor SQL'en står, og en række fra SQL-editoren dukker op i jeres tabel.
Hvis du sidder fast
500ogECONNREFUSEDi terminalen:pgfik ingen connection-string og prøver din egen maskine. Du har glemt--env-file=.env, linjen i.envhedder ikke præcisDATABASE_URL=, eller filen er lavet i PowerShell med>(forkert tegnsæt). Lav.envi VS Code.node: .env: not found: filen findes ikke i den mappe, du står i — eller den hedder.env.txt.password authentication failed: strengen i.enver forkert. Bed ejeren kopiere den igen med Copy snippet.relation "patients" does not exist: du har brugt strengen til dit eget projektlektion15eller et projekt uden tabellen. Brug gruppens.Cannot find module 'pg': kørnpm install pgi den mappe, hvorserver.jsligger.- Lang
SECURITY WARNINGomsslmode: retsslmode=requiretilsslmode=verify-fulli.env. - Serveren svarer langsomt første gang efter en pause: databasen var gået i dvale. Den vågner selv.
- Serveren dør med
Unhandled 'error' eventefter en pause:pool.on("error", …)mangler ipatients.js. .envstår igit status: den er ikke i.gitignore, eller den er allerede committet. Spørg underviseren — passwordet skal så nulstilles.
Hvis du har ekstra tid
- Tilføj
hentPatient(cpr)i repositoryet medWHERE cpr = $1. Hvad returnerer den, når CPR'en ikke findes? - Tegn sekvensdiagrammet fra slidesne for jeres egen
GET, med jeres egne filnavne.
Øvelse 2 — POST og testskemaet
Mål: POST /api/patients gemmer i tabellen. I har kørt testskemaet fra
api.http og skrevet resultatet i projektloggen.
Det skal du lave
- Tilføj
opretPatient(cpr, navn)ipatients.jsmedINSERT … RETURNINGog$1,$2. Eksportér den. - Tilføj
POST /api/patientsiserver.js, over 404-handleren:req.body ?? {},400før databasen,201med den nye patient,500icatch. - Genstart serveren.
- Åbn
api.httpfra lektion 13, og ret body iPOST-requestet til en syntetisk patient, du kan genkende. Brug din egen CPR — skift de to sidste cifre, så den ikke er den samme som gruppens andres:
### Opret patient
POST http://localhost:3000/api/patients
Content-Type: application/json
{"cpr":"0201029994","navn":"Ny Test Person"}
- Kør testskemaet. Skriv resultatet i kolonnen Fik.
| # | Request | Forventet | Fik |
|---|---|---|---|
| 1 | GET /api/patients |
200 og listen |
|
| 2 | POST /api/patients med body |
201 og patienten |
|
| 3 | POST /api/patients uden body |
400 |
|
| 4 | GET /api/patients efter genstart |
200, patienten fra 2 er der |
|
| 5 | GET /api/patients med forkert password i .env |
500 og serverfejl |
|
| 6 | GET /findesikke |
404 |
Requests i api.http — de tre første har I fra lektion 13, tilføj den
sidste:
### Hele listen
GET http://localhost:3000/api/patients
### Opret patient
POST http://localhost:3000/api/patients
Content-Type: application/json
{"cpr":"0201029994","navn":"Ny Test Person"}
### Uden body — skal give 400
POST http://localhost:3000/api/patients
### Ukendt sti — skal give 404
GET http://localhost:3000/findesikke
Statuskoden står øverst i svaret ved siden af filen.
Til række 5: skift ét tegn i passwordet i .env, genstart, kør GET, og
læs fejlen i terminalen — ikke i svaret. Sæt passwordet tilbage, og
genstart igen.
- Kopiér skemaet med jeres resultater ind i projektloggen.
Tjekliste
-
opretPatientbruger$1og$2— ingen+i SQL'en -
400kommer, før databasen bliver kaldt - Alle seks rækker i skemaet giver det forventede
- Svaret på række 5 viser ikke en stacktrace, kun
serverfejl - Passwordet i
.enver sat tilbage
Øvelsen er i hus, når skemaet står i projektloggen med seks rigtige
resultater, og I kan forklare forskellen på 400 og 500.
Hvis du sidder fast
- Ingen Send Request over requestet: REST Client er ikke installeret i
VS Code, eller filen ender ikke på
.http. 400medExpected property name: JSON'en i body er ugyldig. Tjek anførselstegn og kommaer.POSTgiver404: routen står under 404-handleren. Flyt den op.500på etPOST, der burde virke: læs fejlen i terminalen.duplicate keybetyder, at CPR'en allerede findes — fra en tidligere kørsel eller fra en anden i gruppen. Skift CPR i body iapi.http.
Hvis du har ekstra tid
- Send samme
POSTto gange. Det andet svar er500, fordiUNIQUEpåcprafviser rækken. Er500den rigtige kode? Klienten har jo sendt noget forkert, ikke serveren. Find fejlkoden i terminalen (23505), og diskutér i gruppen, hvilken statuskode der passer bedre. - Skift CPR i body i
api.httpigen, og sæt navnet tilx'); DELETE FROM patients; --. Send den. Hvad står der i tabellen bagefter? Hvorfor er de andre patienter der stadig?
Øvelse 3 — Gruppens handling
Mål: Gruppens centrale brugerhandling når hele vejen ned i tabellen: en
formular i mockuppet sender POST, og serveren gemmer i gruppens egen tabel
fra lektion 15. Det er kernen i D2.
Brug syntetiske data. Ingen rigtige CPR, navne eller målinger.
Det skal I nå
- Installér
cors, og erstat jeres egenAccess-Control-Allow-Origin-middleware fra lektion 13.app.use(cors())skal stå før jeres routes:
npm install cors
const cors = require("cors");
app.use(cors());
- Lav et repository til gruppens tabel — en ny fil, opkaldt efter tabellen,
fx
maalinger.js. Én funktion, der opretter en række medINSERT … RETURNINGog pladsholdere. Brugpatients.jssom skabelon. - Lav
POST /api/<jeres tabel>iserver.js. Samme mønster som patienter:400før databasen,201,500icatch. - Test routen fra
api.http, før I rører HTML'en. - I mockuppet: på den side, hvor brugeren laver gruppens handling, lav en
formular, der sender
POSTmedfetch. Udgangspunktet nedenfor er til patienter — ret felterne og URL'en til jeres tabel. - Åbn DevTools → Network, og send formularen. I skal se
OPTIONSmed204og derefterPOSTmed201. - Ejeren af databasen finder rækken i Neons SQL-editor med
SELECT.
Udgangspunkt
<form id="ny-patient">
<label for="cpr">CPR</label>
<input id="cpr" type="text">
<label for="navn">Navn</label>
<input id="navn" type="text">
<p id="fejl" hidden>Kunne ikke gemme. Tjek felterne.</p>
<p id="ok" hidden>Gemt.</p>
<button type="submit">Gem</button>
</form>
const form = document.getElementById("ny-patient");
const fejl = document.getElementById("fejl");
const ok = document.getElementById("ok");
form.addEventListener("submit", async (event) => {
event.preventDefault();
fejl.hidden = true;
ok.hidden = true;
try {
const res = await fetch("http://localhost:3000/api/patients", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
cpr: document.getElementById("cpr").value,
navn: document.getElementById("navn").value
})
});
if (!res.ok) {
fejl.hidden = false;
return;
}
ok.hidden = false;
form.reset();
} catch (err) {
fejl.hidden = false;
}
});
try/catch fanger, at serveren slet ikke svarer — fx fordi den ikke kører.
!res.ok fanger 400 og 500.
Tjekliste
- Gruppens tabel har sin egen repository-fil.
server.jsindeholder ingen SQL - Alle værdier fra requestet går gennem
$1,$2, … - Formularen viser en fejl, hvis et felt mangler (
400) - Network viser
OPTIONS204ogPOST201 - Rækken står i tabellen i Neon
Øvelsen er i hus, når en anden i gruppen kan udfylde formularen og ejeren kan vise rækken i SQL-editoren.
Hvis I sidder fast
OPTIONSmed404i Network:app.use(cors())mangler, eller den står under 404-handleren.OPTIONSmed204, menPOSTbliver blokeret af CORS i Console:app.use(cors())står under jeres routes. Flyt den op, før routes.- Siden genindlæser ved submit:
event.preventDefault()mangler. 400hver gang: tjek, at nøglerne iJSON.stringify({ … })hedder det samme som det, routen læser frareq.body.- Fejlbeskeden kommer, og Network viser intet
POST: serveren kører ikke. - Gruppens tabel har en fremmednøgle til
patients: sendpatient_idmed i body, og tjek i routen, at den er der.
Hvis I har ekstra tid
- Lav
GET /api/<jeres tabel>og en funktion i repositoryet, der henter rækkerne. Vis dem på siden, og hent igen efter201— samme mønster som patienttabellen fra lektion 7. Genstart serveren, og se, at rækkerne er der stadig. - Skriv et testskema som i øvelse 2 for gruppens egne routes, og læg det i projektloggen.
- Tegn sekvensdiagrammet for jeres handling: bruger, browser, route, repository, Neon. Det kan bruges direkte i D2.