Wat is een Schema en Model?
💡 Analogie: Schema = inschrijfformulier
Je wilt leden toevoegen aan sportschool. Je maakt formulier met velden:
Naam: [verplicht, max 50 letters]
Leeftijd: [verplicht, getal, min 16]
Email: [verplicht, moet @ hebben]
Schema in MongoDB doet hetzelfde: welke velden + welke regels.
Model is het object waarmee je formulieren invult en ophaalt.
Waarom handig?
Zonder schema:
- Workout zonder titel → geaccepteerd
- "appel" bij reps → geaccepteerd
- App crasht door foute data
Met schema:
- Title vergeten → Error: "Title required"
- "appel" bij reps → Error: "Must be number"
- Data is altijd correct!
Workout Schema Maken
Schema voor workouts: titel, herhalingen (reps), gewicht (load).
Maak model bestand
Nieuw bestand in src/models/:
src/models/Workout.js
Model begint met hoofdletter!
Schrijf code:
// src/models/Workout.js
import mongoose from 'mongoose';
const Schema = mongoose.Schema;
// Schema = regels voor workout
const workoutSchema = new Schema({
title: {
type: String,
required: true
},
reps: {
type: Number,
required: true
},
load: {
type: Number,
required: true
}
}, {
timestamps: true
});
// Model = object voor maken/ophalen/aanpassen/verwijderen
const Workout = mongoose.model('Workout', workoutSchema);
export default Workout;
type: String- Moet tekst zijntype: Number- Moet getal zijnrequired: true- Moet ingevuld wordentimestamps: true- Voegt automatisch createdAt/updatedAt toe
Workout zonder titel?
Automatisch error:
Validation failed: title: Path `title` is required.
Mongoose checkt het voor je!
Dit is handig!
Zonder schema kan iedereen alles in database gooien. Met schema zeg je: alleen deze velden, met deze types.
Extra validatie (optioneel)
Extra regels toevoegen:
title: {
type: String,
required: true,
trim: true, // Verwijdert spaties
maxlength: 100 // Max 100 tekens
},
reps: {
type: Number,
required: true,
min: 1 // Min 1 (geen 0 of negatief)
}
Basis versie hierboven werkt prima!
Wat doet timestamps?
Mongoose voegt 2 velden toe:
- createdAt - Wanneer aangemaakt?
- updatedAt - Wanneer aangepast?
Voorbeeld:
{
"_id": "...",
"title": "Squats",
"reps": 15,
"load": 50,
"createdAt": "2024-11-25T10:00:00.000Z",
"updatedAt": "2024-11-27T14:30:00.000Z"
}
Model in Routes Gebruiken
Model is klaar, gebruik in routes om data op te slaan/ophalen.
Stap 1: Importeer model
Bovenaan src/routes/workoutRoutes.js:
import Workout from '../models/Workout.js';
Stap 2: Vervang dummy POST
Vervang door echte database code:
// POST nieuwe workout
router.post('/', async (req, res) => {
const { title, load, reps } = req.body;
try {
const workout = await Workout.create({ title, reps, load });
res.status(201).json(workout);
} catch (error) {
res.status(400).json({ error: error.message });
}
});
async (req, res)- Kan wachten op databaseconst { title, load, reps }- Haal data uit POSTtry { }- Probeer ditawait Workout.create()- Sla op en wachtres.status(201)- Status 201 (Created)catch (error)- Als fout, stuur error
Waarom async en await?
Database operaties zijn langzaam. Duurt even voordat MongoDB opslaat.
Probleem zonder await:
Code stuurt response VOORDAT workout is opgeslagen. Gebruiker denkt het is gelukt, maar staat er niet!
Zonder await (FOUT):
// NIET DOEN!
router.post('/', (req, res) => {
const workout = Workout.create({ title, reps, load });
res.json(workout); // TE SNEL!
// workout is undefined hier!
});
Met await (GOED):
// WEL DOEN!
router.post('/', async (req, res) => {
const workout = await Workout.create({ title, reps, load });
res.json(workout); // Nu écht opgeslagen!
});
💡 Simpel gezegd:
await = "wacht tot klaar voordat verder"
async = "deze functie gebruikt await"
Waarom try/catch?
Wat als fout? Iemand vergeet veld of database is offline. Met try/catch vang je error op.
💡 Simpel gezegd:
try { } = "Probeer dit"
catch (error) { } = "Als fout, stuur error terug"
Zonder try/catch crasht server bij elke fout!
Zie de CRUD — Mongoose op de collection
Je hebt nu gezien hoe je een model gebruikt. Maar wat doet elke methode eigenlijk met de collection? Klik op een knop en zie de operatie live op de workouts-collection rechts.
De vier basis-operaties (CRUD):
- Create —
Workout.create({...})voegt een nieuw document toe en geeft 'm terug (met door MongoDB gegenereerde_id). - Read —
Workout.find({})geeft alle docs,Workout.findById(id)geeft één specifiek doc. - Update —
Workout.findByIdAndUpdate(id, {...})wijzigt velden in een bestaand doc. - Delete —
Workout.findByIdAndDelete(id)verwijdert een doc.
Elke methode geeft een Promise terug, dus altijd await gebruiken (binnen een async functie).
Testen met Postman
POST route slaat data op. Maar hoe testen?
Probleem:
In browser kun je alleen GET. Geen POST, PATCH of DELETE.
Postman is programma waarmee je ALLE requests test (GET, POST, PATCH, DELETE). Je kunt JSON data meesturen.
Postman installeren
- Ga naar postman.com/downloads
- Download en installeer
- Open Postman (klik "Skip and go to app")
POST Request Testen
Test of je workout kunt toevoegen.
Stap 1: Nieuwe request
- Klik "New" of "+" voor nieuwe tab
- Selecteer POST
- URL:
http://localhost:4000/api/workouts
Stap 2: Body instellen
- Klik tab "Body"
- Selecteer "raw"
- Kies "JSON" uit dropdown
Stap 3: JSON data
{
"title": "Squats",
"reps": 10,
"load": 50
}
Stap 4: Versturen
Klik "Send" en kijk naar antwoord.
Gelukt! Je ziet:
{
"_id": "6543e8f2d1a2c3b4e5f67890",
"title": "Squats",
"reps": 10,
"load": 50,
"createdAt": "2024-11-22T12:30:00.000Z",
"updatedAt": "2024-11-22T12:30:00.000Z",
"__v": 0
}
Status: 201 Created
Foutmelding? Check:
- Server draait? (
npm run dev) - "Body" → "raw" → "JSON" geselecteerd?
- Aanhalingstekens rond velden?
- URL correct?
GET Request Testen
Check of workout écht is opgeslagen.
In Postman:
- Nieuwe tab (klik "+")
- Methode GET
- URL:
http://localhost:4000/api/workouts - Klik Send
Je ziet array met workouts:
[
{
"_id": "6543e8f2d1a2c3b4e5f67890",
"title": "Squats",
"reps": 10,
"load": 50,
"createdAt": "2024-11-22T12:30:00.000Z",
"updatedAt": "2024-11-22T12:30:00.000Z"
}
]
In MongoDB Atlas:
Bekijk data visueel:
- Ga naar MongoDB Atlas
- Klik "Database"
- Klik "Browse Collections"
- Zie
workout-db→workouts→ je data!
💡 Postman tips:
- Maak "Collection" voor al je requests
- Geef requests namen (bijv. "Create Workout")
- Zo hoef je niet steeds URLs in te typen!
Problemen oplossen
❌ "Validation failed: title required"
Probleem: Title niet meegestuurd
Check:
- Postman Body tab - "raw" en "JSON"?
- JSON heeft "title", "reps" en "load"?
- Correcte body:
{
"title": "Squats",
"reps": 10,
"load": 50
}
❌ "Cannot find module Workout.js"
Probleem: Routes vindt model niet
Check:
- Bestaat
src/models/Workout.js? (hoofdletter W!) - Onderaan Workout.js:
export default Workout;? - Bovenaan routes:
import Workout from '../models/Workout.js';? - Pad klopt? Van routes naar models is
../models/
❌ Status 500 Internal Server Error
Probleem: Fout in server code
Check:
- Kijk in terminal waar
npm run devdraait - Lees error message
- Veelvoorkomende fouten:
- Vergeten
async? - Vergeten
awaitvoorWorkout.create()? - Geen try/catch?
- Vergeten
❌ Geen data in Postman na POST
Check:
- Welke status? 201 = gelukt! 400/500 = lees error
- Check MongoDB Atlas: Database → Browse Collections
- GET request naar
/api/workouts- zie je workout?
💡 Wat is __v veld?
Version number van Mongoose. Houdt bij hoeveel keer document is gewijzigd. Gewoon negeren!
Checklist
✅ Check of je hebt:
- src/models/Workout.js aangemaakt (hoofdletter!)
- Schema met title, reps, load
- timestamps: true toegevoegd
- Model geëxporteerd
- Model geïmporteerd in workoutRoutes.js
- POST route gebruikt Workout.create()
- async en await gebruikt
- Postman geïnstalleerd
- POST request werkt (status 201)
- GET toont nieuwe workout
- Data zichtbaar in MongoDB Atlas
Samenvatting
Je hebt:
- Schema gemaakt (title, reps, load)
- Model gemaakt voor opslaan/ophalen
- POST route aangepast voor echte database
- Postman geïnstalleerd
- Eerste workout opgeslagen!
Volgende Stap
Model klaar en POST werkt! Nu maken we alle CREATE en READ routes compleet.
Maak alle routes voor data ophalen en opslaan