Strapi

Strapi

Introductie

Strapi

  • Open-source Node.js headless CMS

    • ​Open-source: https://github.com/strapi/strapi

    • Headless

      • Traditioneel CMS: presentatie + data

      • Headless CMS: only data

    • Content Management System (CMS)

      • Platform to help manage web site/app content

Strapi

  • Andere voorbeelden van CMS

    • Traditioneel: Wordpress, Drupal, Craft, Umbraco, Magento, Hubspot ...

    • Headless: ContentStack, Sanity, Hygraph, Prismic, Contentful, Ghost ...

Strapi

  • Waarom CMS gebruiken?

Strapi

  • Waarom CMS gebruiken?

    • Sneller en makkelijker om inhoud te beheren

      • Als inhoud snel wijzigt (blogs, webshops ...)

      • Vaak voor niet-developers (marketing, sales, product, administratie ...)

    • Herbruikbare componenten en logica

Strapi

  • Hoe/waarom gaan wij Strapi gebruiken?
    • Snel en eenvoudig een REST API opbouwen die de data zal aanleveren voor de React-applicatie uit onze eindopdracht
    • Inbegrepen:
      • Authorisatie, paginering, filtering, sortering ...

Strapi

npx create-strapi@latest strapi-example1

Need to install the following packages:
create-strapi@5.12.7
Ok to proceed? Yes

? Please log in or sign up. Skip
? Do you want to use the default database (sqlite)? Yes
? Start with an example structure & data? No
? Start with Typescript? No
? Install dependencies with npm? Yes
? Initialize a git repository? Yes

cd strapi-example1
npm run develop
  • Maak een nieuw Strapi-project

Strapi - Admin panel

  • Belangrijkste items uit de navigatiebalk:

    • Content Manager

      • Data beheren (CRUD)

    • Content-Type Builder

      • Datamodel beheren

    • Settings

Strapi

Data beheren

Strapi - datamodel

  • Even terug naar PGM3: relaties

    • One-to-one
    • One-to-many
    • Many-to-one
    • Many-to-many

  • Indien dit ver zit: thuis herhalen!

Strapi - datamodel

  • Strapi heeft 3 data types:

    • Collection types: meerdere entries

      • taken, categorieën, gebruikers, projecten ...

    • Single types: één entry

      • paginatitel, instellingen ...

    • Components

      • valt momenteel buiten onze scope

Strapi - datamodel

  • Stel, we we maken een applicatie met:
    • Studenten (jullie)
    • Klassen (A, B1, B2, C)
    • Cursussen (PGM1, PGM2, Data management 1, ...)
  • Welke relaties moeten we leggen?
    • Klassen ? : ? Studenten
    • Cursussen ? : ? Studenten

Strapi - datamodel

  • Stel, we we maken een applicatie met:
    • Studenten (jullie)
    • Klassen (A, B1, B2, C)
    • Cursussen (PGM1, PGM2, Data management 1, ...)
  • Welke relaties moeten we leggen?
    • Klassen 1 : n Studenten
    • Cursussen n : n Studenten

Strapi - datamodel

  • Open het Strapi admin panel
  • Ga naar Content-Type Builder
    • User: automatisch gemaakt door Strapi
    • Create new collection type
      • ​Display name: Student
      • API ID (Singular): student
      • API ID (Plural): students

Strapi - datamodel

Strapi - datamodel

  • Maak volgende velden aan voor Student
    • firstName (text - required)
    • lastName (text - required)
    • age (number - minimum 16 - maximum 99)
    • studentNumber (text - unique + required)
  • Vergeet niet op te slaan!

Strapi - data toevoegen

  • Manieren om data toe te voegen
    • REST API
    • Admin panel - Content Manager

Strapi - data toevoegen

  • Voeg 3 studenten toe via Content Manager

Strapi

REST API

Strapi - REST API

Strapi - REST API

  • Opnieuw even terug naar PGM3: REST API

  • REST: welke API endpoints?

    • GET     /students

    • GET     /students/:id

    • POST    /students

    • PUT     /students/:id

    • PATCH   /students/:id

    • DELETE  /students/:id

Strapi - REST API

  • Strapi geeft ons standaard voor elke collection type een REST API met volgende endpoints:
    • GET     /students

    • GET     /students/:id

    • POST    /students

    • PUT     /students/:id

    • PATCH   /students/:id

    • DELETE  /students/:id

Strapi - REST API

  • Strapi stelt deze REST API voor collection types standaard beschikbaar via URL
    http://localhost:1337/api/{pluralApiId}
     
  • In ons geval:
    http://localhost:1337/api/students

Strapi - REST API

  • Open Thunder Client in VS Code
  • Maak een nieuwe collectie
  • Maak een nieuwe request "GET all students"
    • GET http://localhost:1337/api/students
  • Test of dit werkt zoals verwacht

Strapi - REST API

  • Error 403? 🤔

Strapi - API tokens

  • Error 403? 🤔
    • Strapi vereist standaard dat je een
      API token meestuurt in alle requests
    • API tokens kan je beheren via Settings - API Tokens
    • Verwijder de bestaande tokens
    • Maak een nieuw token aan
      • Full access + Unlimited duration

Strapi - API tokens

Strapi - API tokens

  • Kopieer de token meteen na het aanmaken,
    deze is slechts eenmalig zichtbaar
  • In Thunder Client, open de collection settings en
    plak de token in tab Auth
    • Token prefix: Bearer

Strapi - API tokens

Strapi - API tokens

  • Als je een token kwijt bent:
    API tokens > Edit > Regenerate
    • ​​​Dit invalideert het bestaande token!

Strapi - REST API

  • Probeer de request opnieuw in Thunder Client.
    • Indien nodig: verwijder de request en maak deze opnieuw aan
    • Controleer of in het Auth tabblad van je request staat
      "Inherit authentication values from Parent"

Strapi - REST API

  • Oefening: voeg in Thunder Client ook requests toe voor de 4 andere endpoints die Strapi standaard beschikbaar stelt
    • GET     /students (OK!)

    • GET     /students/:documentId

    • POST    /students

    • PUT     /students/:documentId

    • PATCH   /students/:id

    • DELETE  /students/:documentId

Strapi

Relaties

Strapi - REST API

  • We hebben voorlopig 1 collection type:
    Students

  • Voeg een nieuwe collection type toe:
    Classes

    • 1 veld: name (text - required + unique)

  • Voeg 4 klassen toe via Content Manager:
    A, B1, B2, C

Strapi - Relaties

  • Hoe definiëren we de relatie tussen beide?

    • A class has many students

Strapi - Relaties

  • Via Content Manager: update de data van studenten zodat ze allemaal tot een klas behoren

  • Voer nogmaals de API call uit om alle studenten op te halen. Kan je zien in welke klas ze zitten?

Strapi - Relaties

  • Standaard geeft Strapi geen gerelateerde data terug 

  • Oplossing: populate query parameter

    • http://localhost:1337/api/students?populate=*

Strapi - Relaties

  • Oefening: maak een applicatie in plain vanilla Javascript waar je een tabel toont met 4 kolommen
    • Voornaam
    • Familienaam
    • Leeftijd
    • Studentennummer
    • Klas
  • De data haal je uiteraard op via Strapi

Strapi - Relaties

  • Oefening: maak een nieuwe pagina met een formulier waar je een nieuwe student kan ingeven
    • Voornaam
    • Familienaam
    • Leeftijd
    • Studentennummer
    • Klas (dropdown)

Strapi - Relaties

  • Gerelateerde data aanmaken bij een PUT of POST
    kan via id

Strapi - Relaties

{
  "data": {
    "firstName": "Judd",
    "lastName": "Trump",
    "age": 39,
    "studentNumber": "7889423719",
    "class": 2
  }
}

Strapi

Architectuur

  • In de vorige oefeningen is onze API token
    opgeslaan in front-end. Waarom is dit bad practice?

Strapi - Architectuur

  • In de vorige oefeningen is onze API token
    opgeslaan in front-end. Waarom is dit bad practice?
    • Token is zichtbaar voor alle gebruikers
  • Hoe kunnen we dit oplossen?
    • Back-end for Front-end (BFF)

Strapi - Architectuur

  • Back-end for Front-end (BFF)

Strapi - Architectuur

  • Back-end for Front-end (BFF)
    • API token
      • → code
      • → omgevingsvariabelen
      • → secret manager ✅ ✅
      • → ...
    • Resultaat:
      gebruikers kennen API token niet meer

Strapi - Architectuur

  • Back-end for Front-end (BFF)
    • Concreet
      • Server 1 (BFF):
        Node.js + Express
      • Server 2:
        Strapi
    • Server 1 acts a proxy voor server 2
      • Requests doorsturen

Strapi - Architectuur

  • Back-end for Front-end (BFF)
    • Andere voordelen:
      • Single responsibility principle:
        data aggregeren en doorgeven in gewenste formaat
      • Error handling
      • Separation of concerns
    • Nadelen:
      • Extra server nodig
      • Bijkomende latency
         

Strapi - Architectuur

Strapi

Filtering & sortering

Strapi - Filtering

  • We kunnen de data van onze REST API ook filteren

  • Voeg nog een aantal studenten toe zodat je er minstens 10 hebt

Strapi - Filtering

  • Oefening: maak nieuwe requests in Thunder Client

    • Alle studenten ouder dan 25

    • Alle studenten jonger dan of gelijk aan 25

    • Alle studenten exact 20 jaar oud

Strapi - Deep filtering

  • Filteren op gerelateerde data noemen we
    deep filtering

  • Oefening: maak een nieuwe request in Thunder Client

    • Haal alle studenten op uit klas A

Strapi - Sortering

  • We kunnen de data ook sorteren

  • Oefening: maak een nieuwe request in Thunder Client

    • Sorteer alle studenten volgens leeftijd (jong -> oud)

    • Maak een nieuwe request voor oud -> jong

Strapi

Paginering

Strapi - Paginering

  • Strapi documentatie

  • Respons van /api/students ->  meta.pagination

    • page

    • pageSize

    • pageCount

    • total

Strapi - Paginering

  • page

    • Huidige pagina

  • pageSize

    • Aantal items per pagina

  • pageCount

    • ​Totaal aantal pagina's

  • total

    • Totaal aantal items

Strapi - Paginering

  • Standaard geeft Strapi de eerste 25 items terug (= pagina 1)

  • Meer items nodig?

    • Volgende pagina opvragen

    • Paginagrootte aanpassen

Strapi - Paginering

  • Query parameters

Strapi - Paginering

Paginering

Paginering

  • Requirements deel 1
    • Indien op pagina 1: "Previous page" disabled
    • Indien op laatste pagina: "Next page" disabled
    • Huidige pagina: blauwe achtergrond + witte tekst
    • Tekst "You are on page {pageNumber}" blijft
      in sync met de huidige pagina
    • Aantal pagina's blijft in sync met pageCount (App)
    • In eerste instantie: toon evenveel knoppen als pagina's
  • Gelukt? Commit!

Paginering

  • Requirements deel 1

Paginering

  • Requirements deel 2
    • Aantal pagina's <= 6:
      toon een knop voor elke pagina
    • Aantal pagina's > 6:
      • Indien op pagina 1, 2 of 3:
        1, 2, 3, 4, ..., 10
      • Indien op pagina 8, 9 of 10:
        1, ..., 7, 8, 9, 10
      • Indien op een andere pagina:
        1, ..., (huidig - 1), huidig, (huidig + 1), ..., 10
  • Het voorbeeld hierboven is voor 10 pagina's
    maar dit moet meeschalen met pageCount in App

Paginering

  • Requirements deel 2

PGM4/3 - Strapi

By kareldesmet

PGM4/3 - Strapi

  • 27