Belangrijke gids voor Rest API-testen en RestAssured

In deze uitgebreide zelfstudie van Rest Assured gaan we de Uitgebreide API-tests, API-testautomatisering en geruststelling in een modulaire aanpak

Wat is RestAssured en het gebruik ervan

Rest Assured is een zeer veel gebruikte open source technologie voor REST API Automation Testing, deze is gebaseerd op een op Java gebaseerde bibliotheek.

Rest Assured werkt samen met Rest API in een headless client-modus, we kunnen hetzelfde verzoek verbeteren door verschillende lagen toe te voegen om het verzoek te vormen en een HTTP-verzoek te maken via verschillende HTTPS-werkwoorden naar de server.

De ingebouwde bibliotheek van Rest Assured biedt enorme methoden en hulpprogramma's voor het valideren van de respons die van de server wordt ontvangen, zoals statusbericht, statuscode en responsbody.

Deze complete serie zelfverzekerde zelfstudies voor het testen van REST API-automatisering bestaat uit de volgende onderwerpen:

RestAssured - De gerustgestelde tutorial api-testen
Wees gerust API-automatisering

Aan de slag: Configuratie van restAssured met Build-tool, dwz Maven / gradle

STAP 1: Als je met maven werkt, voeg dan de volgende afhankelijkheid toe in pom.xml (je kunt ook een andere versie kiezen):

Om aan de slag te gaan met REST Assured, voegt u gewoon de afhankelijkheid toe aan uw project. 


    io. gerustgesteld
    wees gerustgesteld
    4.3.0
    test

Als je met gradle werkt, voeg dan het volgende toe in build.gradle (je kunt ook weer een andere versie kiezen):

testCompile groep: 'io.rest-assured', naam: 'gerustgesteld', versie: '4.3.0'

STAP 2: REST Assured kan heel gemakkelijk worden geïntegreerd en gebruikt met de bestaande unit-testframeworks, zoals Testng, JUnit

Hier gebruiken we testNg volgens het Unit Test Framework betreft.

Zodra de bibliotheken van Rest Assured zijn geïmporteerd, moeten we de volgende statische import aan onze testklassen toevoegen:

importeer statische io.restassured.RestAssured. *;

importeer statische org.hamcrest.Matchers. *;

LET OP: Voor dit aankomende leerdoel zullen we de Ergast Developer API testen, die hier kan worden gevonden. Deze API biedt historische gegevens met betrekking tot Formule 1-races, coureurs, circuits, enz.

Bekendheid met de syntaxis:

Wees gerust, het ondersteunt het BDD-formaat (Augurk Syntax) om de testscripts te schrijven, dwz in het formaat Gegeven / Wanneer / Dan / En, gaan we ervan uit dat u kennis heeft van de syntaxis van BDD / augurk, zo niet, dan raden we aan om 30 minuten tijd te besteden om te begrijpen wat BDD is (Augurk Syntax) en hoe het werkt en het is erg basic.

T-01: Ons eerste script dat in feite het aantal circuits in F1 in 1 valideert met behulp van deze API (http://ergast.com/api/f1/2017/circuits.json)

@Test (description = "Aantal circuits in seizoen 2017 zou 20 moeten zijn") public void validatingNumberOfCircuits () {given (). When (). Get ("http://ergast.com/api/f1/2017/circuits. json "). then (). assertThat (). body ("MRData.CircuitTable.Circuits.circuitId", hasSize (20)); }

Rest API-antwoordvalidatie :

1. Legt de JSON-reactie van het API-verzoek vast.

2. Query's voor circuitId met GPath-expressie 'MRData.CircuitTable.Circuits.circuitId'

3. Verifieert dat de circuitId-elementenverzameling de grootte heeft van 20

Hier gebruiken we Hamcrest-matchers voor verschillende validaties zoals

Er zijn verschillende andere methoden die handig zijn om een ​​bepaalde validatie uit te voeren.

U kunt verder de documentatie van de Hamcrest-bibliotheek raadplegen voor een volledige lijst met overeenkomsten en methoden.

Antwoordcode valideren:

gegeven (). wanneer (). get ("http://ergast.com/api/f1/2017/circuits.json") .then (). assertThat (). statusCode (200);

Validatie van inhoudstype

gegeven (). when (). get ("http://ergast.com/api/f1/2017/circuits.json") .then (). assertThat (). contentType (ContentType.JSON);

Koptekst ‘Content-Length’ valideren

gegeven (). wanneer (). get ("http://ergast.com/api/f1/2017/circuits.json") .then (). assertThat (). header (" Content-Length ", equalTo (" 4551 "));

Meerdere validatie in een enkele test als (met behulp van en () methoden):

@Test (description = "Aantal circuits in seizoen 2017 zou 20 moeten zijn")
    openbare ongeldige validatingNumberOfCircuits () {
        gegeven (). when (). get ("http://ergast.com/api/f1/2017/circuits.json") .then (). assertThat (). header ("Content-Length", equalTo (" 4551 ")). En (). StatusCode (200);
    }

Element / kenmerk van antwoordtekst valideren:

We kunnen JsonPath gebruiken om de waarde van de json-attributen op te halen en assertion te plaatsen met TestNg

@Test (description = "Validatie van serienaam die f1 is")
    openbare ongeldige validatingSeriesName () {
        // Converteer ResponseBody naar String
        String responseBody = gegeven (). When (). Get ("http://ergast.com/api/f1/2017/circuits.json") .getBody (). AsString ();
        // Maak JsonPath-object door de antwoordtekst als een tekenreeks door te geven
        JsonPath resJson = nieuwe JsonPath (responseBody);
        // Haal de kenmerkwaardereeks op onder MRData
        String seriesName = resJson.getString ("MRData.series");
        // Gebruiker TestNg Assertion
        Assert.assertEquals ("f1", seriesName);
    }

Op dezelfde manier konden we de waarde van XML-respons krijgen met XMLPath. Hier werken we met JSON en daarom hebben we hier JSonPath gebruikt

RESTful API's ondersteunen slechts twee soorten parameters:

A. Query-parameters: Hier worden parameters toegevoegd aan het einde van het API-eindpunt en kunnen ze worden geïdentificeerd door het vraagteken en vormen een sleutelwaardepaar zoals 

https://www.google.com/search?q=https://www.wikipedia.org/

Hier in de bovenstaande API is 'q' de parameter en 'https://www.wikipedia.org/' is de waarde van die parameter, als we zoeken 'IETS_ELSE_TEXT'zouden we de waarde van de parameter kunnen vervangen 'q' met 'IETS_ELSE_TEXT'in plaats van https://www.wikipedia.org/.

B. Padparameters: Dit zijn het onderdeel van het RESTful API-eindpunt. 

bijv. eindpunt dat we eerder gebruikten: http://ergast.com/api/f1/2017/circuits.json, hier is "2017" een padparameterwaarde.

Om een ​​resultaat voor het jaar te krijgen 2016 zouden we 2017 kunnen vervangen door 2016 dan geeft de API de responsbody voor 2016.

Tests met behulp van Path Params voor RestAssured

@Test (description = "Validatie van het aantal circuits met behulp van padparameters")
    openbare ongeldige testWithPathParams () {
        String seasonNumber = "2017";
       String responseBody = gegeven (). PathParam ("seizoen", seizoennummer) .when (). Get ("http://ergast.com/api/f1/{season}/circuits.json") .getBody (). AsString ();
        // Maak JsonPath-object door de antwoordtekst als een tekenreeks door te geven
        JsonPath resJson = nieuwe JsonPath (responseBody);
        // Haal de kenmerkwaardereeks op onder MRData
        String seriesName = resJson.getString ("MRData.series");
        // Gebruiker TestNg Assertion
        Assert.assertEquals ("f1", seriesName);
    }

Tests met behulp van Query Params voor RestAssured

@Test (description = "Validatie van Google Zoeken met Query Params")
    openbare ongeldige testWithPathParams () {
        String searchItem = "https://www.wikipedia.org/";
  gegeven (). queryParam ("q", searchItem) .when (). get ("https://www.google.com/search") .then (). assertThat (). statusCode (200);
    }

Parametriserende tests:

We kunnen gegevensgestuurde tests uitvoeren (dwz hetzelfde testscript zal meerdere keren worden uitgevoerd met verschillende sets invoergegevens en verschillende uitvoergegevens leveren) met behulp van Rest Assured 

STAP 1: Een testNg-gegevensprovider gemaakt.

STAP 2: Gebruik de gegevensprovider in het testscript.

@DataProvider (name = "seasonsAndRaceNumbers")
    openbaar object [] [] testDataFeed () {
        retourneer nieuw object [] [] {
                {"2017", 20},
                {"2016", 21}
        };
    }
@Test (description = "Aantal circuits validatie in verschillende seizoenen", dataProvider = "seizoenenAndRaceNummers") public void circuitNumberValidation (String seasonYear, int raceNumbers) {given ().pathParam ("seizoen", seizoenjaar) .when (). get ("http://ergast.com/api/f1/{seizoen}/circuits.json "). then (). assertThat (). body (" MRData.CircuitTable.Circuits.circuitId ", hasSize (raceNummers)); }

Werken met meerwaardige parameters met RestAssured 

Parameters met meerdere waarden zijn die parameters die meer dan één waarde per parameternaam hebben (dwz een lijst met waarden per paramKey), we kunnen ze adresseren zoals hieronder:

gegeven (). param ("paramKey", "paramValue1", "paramaValue2"). when (). get ("API URL");

Of we kunnen een lijst voorbereiden en de lijst doorgeven als de waarde van de paramKey, zoals:

Lijst paramValue = nieuwe nieuwe ArrayList ();
paramValue.add ("paramvalue1");
paramValue.add (“paramvalue2);
gegeven (). param ("paramKey", paramValue) .when (). get ("API URL");
Werken met cookie met RestAssured 
gegeven (). cookie ("cookieK", "cookieVal"). when (). get ("API URL");

Or 

We kunnen hier ook een cookie met meerdere waarden specificeren, zoals:

gegeven (). cookie ("cookieK", "cookieVal1", "cookieVal2"). when (). get ("API URL");

Werken met kopteksten:

We kunnen in een verzoek specificeren met behulp van header / headers zoals:

gegeven (). header ("headerK1", "headerValue1"). header ("headerK2", "headerValue2"). when (). get ("API URL");

Werken met contentType:

gegeven (). contentType ("application / json"). when (). get ("API URL");

Or 

gegeven (). contentType (ContentType.JSON) .when (). get ();

Meet de reactietijd:

lange timeDurationInSeconds = get ("API URL"). timeIn (SECONDS);

Rest API-verificatie

REST verzekerd ondersteunt verschillende autorisatieschema's, bijv. OAuth, samenvatting, certificaat, formulier en preventieve basisauthenticatie. We kunnen ofwel authenticatie instellen voor elk verzoek 

hier is een voorbeeldverzoek met hetzelfde:

gegeven (). auth (). basic ("uName", "pwd"). when (). get ("URL") ..

Aan de andere kant authenticatie en gedefinieerd in de onderstaande benadering voor de HTTP-verzoeken:

RestAssured.authentication = basic ("uName", "pwd");

Basic AUTH-typen:

Er zijn twee soorten basisauthenticatie: "preventieve" en "challengeed token basic authentication".

Preventieve basisauthenticatie:

Hierdoor worden de basisverificatiegegevens verzonden, zelfs voordat de server in bepaalde situaties een ongeautoriseerd antwoord geeft terwijl het verzoek wordt geactiveerd, waardoor de overhead voor het maken van een extra verbinding wordt verminderd. Dit zijn meestal veel voorkomende situaties, tenzij we testen of de servers kunnen uitdagen. 

Bijv.

gegeven (). auth (). preemptive (). basic ("uName", "pwd"). when (). get ("URL"). then (). statusCode (200);

Betwiste basisverificatie

Aan de andere kant zal "challengeed basic authentication" REST Assured de inloggegevens niet verstrekken tenzij de server er expliciet om heeft gevraagd, dwz de server gooit de ongeautoriseerde reactie. Na dat UnAuthorized antwoord stuurt Rest-Assured een ander verzoek naar de server, namelijk de Auth.

gegeven (). auth (). basic ("uName", "pwd"). when (). get ("URL"). then (). statusCode (200);

Digest-verificatie

Op dit moment wordt alleen "challengeed digest authentication" overwogen. bv:

gegeven (). auth (). digest ("uName", "pwd"). when (). get ("URL"). then (). statusCode (200); 

Formulierverificatie

We zouden dit voornamelijk kunnen bereiken in 3 verschillende benaderingen, afhankelijk van de toepassing / scenario's:

Formulierauthenticatie is een van de meest populaire vormen via internet, waarbij een gebruiker zijn inloggegevens invoert, dwz gebruikersnaam en wachtwoord, via een webpagina en inlogt op het systeem. Dit kan worden aangepakt met behulp van dit 

gegeven (). auth (). form ("uName", "pWd").
wanneer (). get ("URL");
dan (). statusCode (200);

Hoewel dit misschien niet werkt zoals het optimaal is, kan het slagen of mislukken, afhankelijk van de complexiteit van de webpagina. Een betere optie is om deze details te verstrekken bij het instellen van de formulierauthenticatie in de onderstaande benadering:

gegeven (). auth (). form ("uName", "pwd", new FormAuthConfig ("/ 'vermeld hier de naam van de formulieractie die deel uitmaakt van de html-paginacode onder de formuliertag'", "uName", "pwd ")). when (). get (" URL "). then (). statusCode (200);

In deze benadering zal de REST Assured intern niet nodig hebben om een ​​extra verzoek te activeren en door de webpagina te parseren. 

Als u de standaard Spring Security gebruikt, dan een vooraf gedefinieerde FormAuthConfig wordt geactiveerd.

gegeven (). auth (). form ("uName", "Pwd", FormAuthConfig.springSecurity ()). when (). get ("URL"). then (). statusCode (200);

OPMERKING: Als we aanvullende invoergegevens samen met formulierauth willen verzenden, kunnen we het onderstaande schrijven:

gegeven (). auth (). form ("uName", "pwd", formAuthConfig (). withAdditionalFields ("firstInputField", "secondInputField"). ..

CSRF:

CSRF staat voor Cross-site request forgery.

Tegenwoordig is het heel gebruikelijk dat de server een CSRF-token geeft bij het antwoord om de CSRF-beveiligingsaanvallen te voorkomen. REST Assured ondersteunt dit door een automatische parser te gebruiken en een CSRF-token aan te bieden. 

Om dit te bereiken, moet REST Assured een extra verzoek doen en de website ontleden (enkele positie).

We kunnen CSRF-ondersteuning inschakelen door de onderstaande code te schrijven:

gegeven (). auth (). form ("uName", "pwd", formAuthConfig (). withAutoDetectionOfCsrf ()). when (). get ("URL"). then (). statusCode (200);

Naast om REST Assured te helpen en het parseren vlekkeloos en robuuster te maken, kunnen we de CSRF-veldnaam opgeven (hier gaan we ervan uit dat we Spring Security-standaardwaarden gebruiken en kunnen we vooraf gedefinieerde springSecurity FormAuthConfig gebruiken):

gegeven (). auth (). form ("uName", "pwd", springSecurity (). withCsrfFieldName ("_ csrf")). when (). get ("URL"). then (). statusCode (200);

Standaard wordt de CSRF-waarde doorgegeven als een formulierparameter met het verzoek, maar we kunnen configureren om het als een koptekst te verzenden als dit vereist is, zoals hieronder:

gegeven (). auth (). form ("uName", "pwd", springSecurity (). withCsrfFieldName ("_ csrf"). sendCsrfTokenAsHeader ()). when (). get ("URL"). then (). statusCode (200);

OAuth 1:

OAuth 1 vereist dat Scribe in het klassenpad staat. Om oAuth 1-authenticatie te gebruiken, kunnen we het volgende doen:

gegeven (). auth (). oauth (..). when (). ..

OAuth 2:

gegeven (). auth (). oauth2 (accessToken) .when (). ..

In de bovenstaande benadering wordt het OAuth2 accessToken in een header beschouwd. Om meer expliciet te zijn, kunnen we ook doen:

gegeven (). auth (). preventief (). oauth2 (accessToken) .when (). ..

Bestand, byte-array, invoerstroom of tekst doorgeven in Request:

Bij het verzenden van grote hoeveelheden gegevens naar de server is het over het algemeen een gebruikelijke benadering om de meerdelige formuliergegevenstechniek te gebruiken. Wees gerust, bied methoden genaamd multiPart waarmee we een bestand, byte-array, invoerstroom of tekst kunnen specificeren om te uploaden. 

gegeven (). multiPart (nieuw bestand ("/ File_Path")). when (). post ("/ upload");

Aanmaken van een POST-aanvraag met een gerust hart

Met POST- en PUT-verzoeken sturen we gegevens naar de server en in feite het maken van bronnen / bijwerken van bronnen, u kunt dit beschouwen als een schrijf- of updatebewerking.

De gegevens die in een POST-verzoek naar de server worden verzonden, worden in de hoofdtekst van een HTTP-verzoek / API-oproep verzonden. 

Het type inhoud of gegevens dat wordt verzonden, kan een ander formaat hebben, afhankelijk van de API, dwz XML, JSON of een ander formaat wordt gedefinieerd door de Content-Type-header. 

Als de POST-body uit de JSON-gegevens bestaat, is de header Content-Type application/json. Op dezelfde manier zou voor een POST-verzoek dat uit een XML bestaat de header Content-Type van het type application/xml zijn.

Hier is het onderstaande codefragment voor hetzelfde:

gegeven (). contentType ("application / json"). param ("pk", "pv"). when (). body ("JsonPAyloadString"). post ("url"). then (). assertThat (). statusCode (200);

OPMERKING: Er zijn verschillende manieren waarop we de payload / request-body kunnen doorgeven aan de methode "body" zoals String (zoals weergegeven in het bovenstaande fragment), JsonObject, als een bestand enz.

PUT-verzoek met geruststelling:

gegeven (). contentType ("application / json"). param ("pk", "pv"). when (). body ("JsonPAyloadString"). put ("url"). then (). assertThat (). statusCode (200);

Verzoek verwijderen met gerustgesteld:

gegeven (). contentType ("application / json"). param ("pk", "pv"). when (). delete ("url"). then (). assertThat (). statusCode (200);

En op die manier kunnen we verschillende Rest API-aanroepen maken voor verschillende API-werkwoorden (GET / POST / PUT / DELETE enz.)

Serialisatie en deserialisatie in Java:

Serialisatie is in feite het verwerken of converteren van de objectstatus naar een bytestroom. Aan de andere kant is de deserialisatie in Java het verwerken of converteren van de bytestroom naar een daadwerkelijk Java-object in het geheugen. Dit mechanisme wordt gebruikt bij persistentie van Object.

Hieronder is het blokschema voor hetzelfde 

1ESLuGPTk5gUs9eA5 OXkbw KyHeRnO9TdX bg OEo3 ZD7BJ9HqLY HcOaf9saeK137JSzmDj7 TY2WmrlVogzLzkgmN1gvLvyaF6cdGb6psTcv0HVH98J45L4b1a0c3ucUvJ6p

Voordelen van de serialisering

A. Om de staat van een object op te slaan / te behouden.

B. Om een ​​object over een netwerk te laten stromen.

Serialisatie bereiken met JAVA

Om een ​​Java-object te kunnen serialiseren, moeten we de interface java.io.Serializable implementeren.

De klasse ObjectOutputStream die de methode writeObject () bevat die verantwoordelijk is voor het serialiseren van een object.

De klasse ObjectInputStream bevat ook een andere methode genaamd readObject () die verantwoordelijk is voor het deserialiseren van een object.

klassen die java.io.Serializable interface implementeren, kan hun object alleen worden geserialiseerd.

Serializable is slechts een markeringsinterface en net als andere marktinterfaces heeft het geen gegevenslid of methode die eraan is gekoppeld. Die wordt gebruikt om Java-klassen te "markeren" zodat objecten van deze klassen bepaalde mogelijkheden krijgen. Net als enkele andere markerinterfaces zijn: - Cloneable en Remote etc.

OPMERKING:

1. Als een bovenliggende klasse een serialiseerbare interface heeft geïmplementeerd, is de onderliggende klasse niet vereist om hetzelfde te implementeren, maar omgekeerd is dit niet van toepassing.

2. Alleen niet-statische gegevensleden worden opgeslagen met het serialiseringsproces.

3. Statische gegevensleden en ook de tijdelijke gegevensleden worden niet opgeslagen door de serialisering. Dus als we de waarde van het niet-statische gegevenslid niet hoeven op te slaan, kunnen we deze tijdelijk maken.

4. Constructor wordt nooit aangeroepen wanneer een object wordt gedeserialiseerd.

STAP 1: De eerste stap is eigenlijk het creëren van een klasse die de Serializable interface implementeert:

importeer java.io.Serializable;
public class Dummy implementeert Serializable {
    privé int i;
    privé String-gegevens;
    public Dummy (int i, String-gegevens)
    {
        dit.i = ik;
        this.data = gegevens;
    }
}

STAP 2: Maak een klasse om deze te serialiseren:

importeer java.io.FileNotFoundException;
importeer java.io.FileOutputStream;
importeer java.io.IOException;
importeer java.io.ObjectOutputStream;
openbare klasse Serialize {
    public static void Serialization (Object classObject, String fileName) {
        proberen {
            FileOutputStream fileStream = nieuwe FileOutputStream (bestandsnaam);
            ObjectOutputStream objectStream = nieuwe ObjectOutputStream (fileStream);
            objectStream.writeObject (classObject);
            objectStream.close ();
            fileStream.close ();
        } vangen (FileNotFoundException e) {
            // TODO Automatisch gegenereerd catch-blok
            e.printStackTrace ();
        } vangen (IOException e) {
            // TODO Automatisch gegenereerd catch-blok
            e.printStackTrace ();
        }
    }
    public static void main (String [] args) {
        Dummy dummyObj = nieuwe Dummy (10, "Lambda-geeks");
        Serialisatie (dummyObj, "DummSerialized");
    }
}

STAP 3: Zodra stap 2 met succes is voltooid, krijgt u te zien dat er een bestand is gemaakt met wat gegevens erin, die gegevens zijn in feite geserialiseerde gegevens van de objectleden.

  Deserialisatie met java:

Hier is het onderstaande codefragment:

 openbare statische Object DeSerialize (String bestandsnaam)
    {
        proberen {
            FileInputStream fileStream = nieuwe FileInputStream (nieuw bestand (bestandsnaam));
            ObjectInputStream objectStream = nieuwe ObjectInputStream (fileStream);
            Object deserializeObject = objectStream.readObject ();
            objectStream.close ();
            fileStream.close ();
            terug deserializeObject;
        } vangen (FileNotFoundException e) {
            e.printStackTrace ();
        } vangen (IOException e) {
            e.printStackTrace ();
        } vangen (ClassNotFoundException e) {
            e.printStackTrace ();
        }
        null teruggeven;
    }

Driver Code gaat als volgt:

 public static void main (String [] args) {
      / * Dummy dummyObj = nieuwe Dummy (10, "Lambda-geeks");
        Serialisatie (dummyObj, "DummSerialized");
        System.out.println ("------------------------------------------- ------------------------------- ");
      */
        Dummy deSerializedRect = (Dummy) DeSerialize ("DummSerialized");
        System.out.println ("Gegevens van geserialiseerd object" + deSerializedRect.print ());
        System.out.println ("------------------------------------------- ------------------------------- ");
    }

JSONPATH Meer syntaxis / query:

Laten we een JSON aannemen zoals hieronder:

{
  "OrganizationDetails": "Dummy Details van de organisatie",
  "Region": "Azië",
  "Emp-Details": [
    {
      "Org": "lambda-Geeks",
      "Informatie": {
        "Ph": 1234567890,
        "Add": "XYZ",
        "Leeftijd": 45
      }
    },
    {
      "Org": "lambda-Geeks-2",
      "Informatie": {
        "Ph": 2134561230,
        "Add": "ABC",
        "Leeftijd": 35
      }
    }
  ]
}

in de bovenstaande JSON worden de OrganizationDetails & Region genoemd als Leaf-knooppunt, omdat ze geen verdere onderliggende knooppunten / -elementen hebben, maar omdat aan de andere kant de Emp-Details een kindknooppunt hebben, vandaar dat het geen Leaf-knooppunt wordt genoemd.

Als we hier proberen de waarde van OrganizationDetails te krijgen, moeten we het volgende gebruiken:

$ .OrganizationDetails 
Dit resulteert in:
 [
  "Dummy Details van de organisatie"
]

Net als Wise om de gegevens voor de regio te krijgen, moeten we schrijven:

$ .Region 

Als we de waarde van Leeftijd voor de 1e werknemer willen vinden, kunnen we schrijven:

$ .Emp-Details [0] .Information.Age
Dit resulteert in:
[
  45
]

Voor de leeftijd van de 2e werknemer konden we schrijven

$ .Emp-Details [1] .Information.Age
Dit resulteert in: [35]

Op deze manier kunnen we de JsonPath-expressie / -query achterhalen om de gegevens voor de respectieve velden in de JSON op te halen.