Een complete gids voor HTTP-aanvragen in Node.js

INHOUDSOPGAVE

Voeg in enkele minuten lidmaatschappen toe aan uw Webflow-project.

Probeer Memberstack

Meer dan 200 gratis kloonbare Webflow componenten. Aanmelden is niet nodig.

Bekijk bibliotheek

Voeg in enkele minuten lidmaatschappen toe aan uw React-project.

Probeer Memberstack
Victor Jonah

Dit artikel gaat meer in op HTTP, HTTP-verzoeken, manieren om deze verzoeken in Node te doen en hoe we fouten kunnen afhandelen.

HTTP-verzoeken doen in Node is een van de belangrijkste dingen die je als ontwikkelaar doet en hoewel het eenvoudig is om uit te voeren, is er nog steeds veel dat je moet begrijpen of waarvan je je waarschijnlijk bewust moet zijn. HTTP-verzoeken gaan allemaal over het overbrengen van gegevens via een netwerk dat is gebouwd op een client-server model.

De onderliggende technologie is het HTTP (Hypertext Transfer Protocol) dat wordt gebruikt om verzoeken en antwoorden via het internet te structureren. Het werd oorspronkelijk ontworpen om communicatie tussen webservers en webbrowsers mogelijk te maken door alleen html te verzenden, maar het protocol wordt nu enorm veel gebruikt voor verschillende doeleinden. In dit artikel richten we ons op HTTP-verzoeken, het protocol waarbij een stuk data wordt opgevraagd bij een server.

In dit artikel bespreken we meer over HTTP, HTTP-verzoeken, manieren om deze verzoeken te doen in Node en hoe we fouten kunnen afhandelen.

Vereisten

  • Voor dit artikel moet je Node op je computer geïnstalleerd hebben en alle voorbeelden hier draaien op Node v14.15.4, dus als je dit of hoger hebt op het moment dat je dit artikel leest, zit je goed.
  • Er is ook een basiskennis van JavaScript en van het uitvoeren van elk codevoorbeeld nodig om de inhoud van dit artikel te begrijpen.

Wat zijn HTTP-verzoeken in Node

Voordat we het hebben over wat HTTP-verzoeken zijn in Node, moeten we eerst begrijpen wat verzoeken in het algemeen zijn. Verzoeken zijn een manier om informatie uit te wisselen tussen een client en een server. De client en server moeten aanwezig zijn voordat we het een verzoek kunnen noemen. De client moet degene zijn die een verzoek initieert, waarna de server op zijn beurt een antwoord stuurt in overeenstemming met het verzoek.

Het doen van een HTTP-verzoek in Node is zo belangrijk als wat en er zijn onderdelen waarmee we rekening moeten houden om een verzoek te doen in Node. De belangrijkste specificaties die beschrijven hoe je een HTTP-verzoek doet, staan in RFC 7230. De HTTP-aanvraag bevat drie elementen, waaronder:

  1. De request methode die ik eerder heb aangeroepen.
  2. Het doel, waar het verzoek naartoe gaat. Dit is meestal de URL.
  3. De protocolnaam en de versie ervan.

Laten we eens kijken naar de onderdelen waarmee we rekening moeten houden voordat we een HTTP-verzoek doen. Het eerste dat we moeten opmerken is dat we een verzoek sturen naar een URL en dat er een aantal acties zijn die samen met die URL moeten worden verstuurd.

  • Methode (GET, POST, PUT, DELETE, enz.): Als we bijvoorbeeld een verzoek doen aan een URL in onze browser, zoals https://:www.google.com, gebruiken we de GET-methode en ons antwoord zal zeker de bron zijn (wat we zien in onze browser).

URL voor verzoek: https://www.google.com/
Aanvraagmethode: GET
Statuscode: 200 
Adres op afstand: ******
Beleid verwijzer: oorsprong

In het bovenstaande geval hebben we niets ernstigs gedaan, maar alleen om gegevens gevraagd. De methoden hier zijn slechts conventies voor wat er op de server moet gebeuren. POST stuurt gegevens naar de server om te worden opgeslagen, PUT stuurt ook naar de server maar werkt de bron bij die al op de server staat en DELETE verwijdert een bron op de server. 

  • Gegevens: Dit is een ander belangrijk onderdeel bij het doen van een verzoek, omdat de kans groot is dat je gegevens naar de server stuurt. Als je de GET-methode gebruikt, hoef je niet per se gegevens te verzenden. Maar bij andere methoden, zoals POST, moet je wel gegevens verzenden.

POST /test HTTP/1.1
Host: foo.example
Inhoud-Type: toepassing/x-www-formulier-urlencoded
Inhoud lengte: 27

name=Victor&email=emailadres

  • In het bovenstaande geval sturen we de gegevens (naam en e-mail) naar de server voor een doel dat bekend is bij de client.
  • Headers: Headers zijn wat ik noem aanvullende informatie of metadata die samen met het verzoek worden verzonden. Ze werken niet alleen met het verzoek, maar ook met het antwoord. Hoewel het klinkt alsof ze minder worden gebruikt, zijn ze nog steeds hard nodig om informatie te geven over het onderwerp van het verzoek. 
  • De headers worden dus meestal geschreven door de client (jij) terwijl andere automatisch worden gedaan. Zoals ik al eerder zei, headers kunnen enigszins belangrijk zijn, maar dit hangt af van het type API waarmee je werkt. Hieronder staat een voorbeeld van MDN over hoe headers eruit zouden moeten zien:

GET /home.html HTTP/1.1
Host: ontwikkelaar.mozilla.org
Accepteren: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Taal: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Verwijzer: https://developer.mozilla.org/testpage.html
Verbinding: keep-alive
Upgrade-Insecure-Requests: 1
If-Modified-Since: Mon, 18 Jul 2016 02:36:04 GMT
If-None-Match: "c561c68d0ba92bbeb8b0fff2a9199f722e3a621a"
Cache-Control: max-age=0

Om meer te weten te komen over het veld Request headers, kun je meer lezen in RFC 7231, sectie 5.

  • Authenticatie: We moeten dit nog steeds een request component noemen, ook al kunnen we het gebruiken of doen wat het doet in de Headers of als Data. Vaker zul je een token naar de server sturen zodat de server zich kan authenticeren en weet wie je bent voordat hij je toegang geeft tot de bron.

Machtiging:  

Dit is slechts een kort overzicht van de onderdelen van een HTTP-verzoek. Met dit in gedachten kunnen we verder gaan met bespreken hoe we deze HTTP-verzoeken in Node kunnen doen.

Manieren om HTTP-verzoeken te doen in Node

Omdat we ons voornamelijk richten op Node, zullen we kijken naar 5 manieren om HTTP GET en POST verzoeken te doen. Ons doel is om te kijken naar de verschillende manieren en de overeenkomsten of beter nog een handigere manier om verzoeken af te handelen. Ik wil er ook op wijzen dat dit niet bedoeld is om je te vertellen welke beter is, maar eerder welke handig is voor jou.

1. HTTP-module 

Dit is een ingebouwde standaardbibliotheek of -module die in principe wordt gebruikt om een HTTP-client en -server te bouwen. We kunnen bijvoorbeeld een webserver maken die luistert naar HTTP verzoeken en we kunnen dezelfde module gebruiken om HTTP verzoeken te doen. 

Node biedt http en https, aparte modules. Met de laatste kun je communiceren via SSL, waarbij de communicatie wordt versleuteld met behulp van een certificaat. Je kunt https gebruiken als je een verzoek doet met een https url. Laten we eens kijken hoe we een GET- en POST-verzoek kunnen doen met de https-module.


const https = require("https");

https
  .get(`https://reqres.in/api/users`, resp => {
    let data = "";

    // A chunk of data has been recieved.
    resp.on("data", chunk => {
      data += chunk;
    });

    // The whole response has been received. Print out the result.
    resp.on("end", () => {
      let url = JSON.parse(data).message;
      console.log(url);      
    });
  })
  .on("error", err => {
    console.log("Error: " + err.message);
  });

In de bovenstaande code maken we een GET request naar de Dogs API, de resp is een object en daarbinnen zijn twee events waar we naar moeten luisteren; de on data en on end. Met de on data, streamen we de data naar ons in chunks (stukjes voor stukjes) en met de on end, luisteren we en parsen we onze data als het klaar is. We hebben ook de error handler event on error die luistert naar fouten.

Laten we eens kijken naar het maken van een POST-verzoek met de https-module:


const https = require("https");

const options = {
  hostname: 'yourapi.com',
  port: 443,
  path: '/todos',
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Content-Length': data.length
  }
}

https
  .request(options, resp => {
    // log the data
    resp.on("data", d => {
      process.stdout.write(d);
    });
  })
  .on("error", err => {
    console.log("Error: " + err.message);
  });

Je kunt altijd de https.request gebruiken omdat deze automatisch de GET-methode gebruikt als je niets opgeeft en ook de on end event underhood aanroept.

2. Axios 

Volgens Axios is het een op beloftes gebaseerde HTTP-client voor de browser en ook Node. Dit betekent dat het een bibliotheek van derden is die op elk JavaScript-project kan worden gebruikt. Het gebruikt XMLHttpRequest onder de kap om aanvragen te doen en doet dat ook nog eens op een soepele manier. 

De functies omvatten het onderscheppen van verzoeken en reacties, het annuleren van verzoeken, het transformeren van verzoeken en reactiegegevens, en het belangrijkste, het verandert de reacties automatisch in JSON-gegevens.

Om Axios met npm te installeren, voer je dit commando uit:


$ npm install axios

Laten we een eenvoudig GET-verzoek doen en de reactie bekijken.


const axios = require('axios').default;

async function getUsers() {
  try {
    const response = await axios.get(`https://reqres.in/api/users`);
    console.log(response);
  } catch (error) {
    console.error(error);
  }
}
getUsers()

Eerst hebben we de Axios-bibliotheek nodig, doen we een verzoek naar de url met axios.get() en loggen we het antwoord. Dit is een vlotte aanvraag met minder code omdat Axios alle grote dingen voor ons doet.

Bekijk het antwoord hieronder:


{
  status: 200,
  statusText: 'OK',
  headers: {
    date: 'Sat, 26 Mar 2022 13:51:08 GMT',
    'content-type': 'application/json; charset=utf-8',
    'content-length': '996',
    connection: 'close',
    'x-powered-by': 'Express',
    'access-control-allow-origin': '*',
    etag: 'W/"3e4-2RLXvr5wTg9YQ6aH95CkYoFNuO8"',
    via: '1.1 vegur',
    'cache-control': 'max-age=14400',
    'cf-cache-status': 'HIT',
    age: '6320',
    'accept-ranges': 'bytes',
    'expect-ct': 'max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"',
    'report-to': '{"endpoints":[{"url":"https:\\/\\/a.nel.cloudflare.com\\/report\\/v3?s=kXKzeaxshfg8WPvQvms%2FJ6YvtrgnJh3GzGw4O62LPjVjC6n24KQo6c24Tix1NHo6qfLO9V%2FLaOoqJi%2FHt2GQceMnobhDFRDIExmnDrD3kY%2FB%2Fim6tWp1BkGBi8E%3D"}],"group":"cf-nel","max_age":604800}',
    nel: '{"success_fraction":0,"report_to":"cf-nel","max_age":604800}',
    server: 'cloudflare',
    'cf-ray': '6f205bffa85f0871-SEA',
    'alt-svc': 'h3=":443"; ma=86400, h3-29=":443"; ma=86400'
  },
  config: {
    transitional: {
      silentJSONParsing: true,
      forcedJSONParsing: true,
      ...
      ...
      ...
  data: {
    page: 1,
    per_page: 6,
    total: 12,
    total_pages: 2,
    data: [ [Object], [Object], [Object], [Object], [Object], [Object] ],
    support: {
      url: 'https://reqres.in/#support-heading',
      text: 'To keep ReqRes free, contributions towards server costs are appreciated!'
    }
  }
}

Gemakkelijk te begrijpen en met respons te werken.

Laten we daarmee een POST-verzoek doen aan dezelfde API. 


const axios = require('axios').default;

const data = {
  "name": "victor",
  "job": "writer"
}

async function addUser(data) {
  try {
    const response = await axios.post(`https://reqres.in/api/users`, data);
    console.log(response);
  } catch (error) {
    console.error(error);
  }
}

addUser()

Onze axios.post() neemt twee parameters aan, namelijk de url en de gegevens die naar de server moeten worden verzonden. Als we kijken naar de respons hieronder, krijgen we statuscode context dat het succesvol is verzonden.

Tip: druk op elk moment op control+c om REPL te openen.


{
  status: 201,
  statusText: 'Created',
  headers: {
    date: 'Sat, 26 Mar 2022 14:07:58 GMT',
    'content-type': 'application/json; charset=utf-8',
    'content-length': '51',
    connection: 'close',
    'x-powered-by': 'Express',
    'access-control-allow-origin': '*',
    etag: 'W/"33-wWfab/HlR/+j60wjrpfaMpVmAek"',
    via: '1.1 vegur',
    'cf-cache-status': 'DYNAMIC',
    'expect-ct': 'max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"',
    'report-to': '{"endpoints":[{"url":"https:\\/\\/a.nel.cloudflare.com\\/report\\/v3?s=WCBCWafrH4GtOHMHIwcxuA7XfKR3PnH3pIuyH44ugHT1hgudiMHwBBv3x8VIsW0WwxC5N6RPKUcO3IwptR99V5kp%2Bcb%2Fp4NJ9bHVQOvbUcK22YfHElZ72AtFk0w%3D"}],"group":"cf-nel","max_age":604800}',
    nel: '{"success_fraction":0,"report_to":"cf-nel","max_age":604800}',
    server: 'cloudflare',
    'cf-ray': '6f2074a4fd2a27d2-SEA',
    'alt-svc': 'h3=":443"; ma=86400, h3-29=":443"; ma=86400'
  },
  ...
  ...
  ...
  },
  data: { id: '210', createdAt: '2022-03-26T14:07:58.464Z' }
}

Samenvattend lijkt deze manier om een verzoek in te dienen me gemakkelijk omdat veel van het zware werk van je wordt overgenomen en met een heel mooi antwoord.

3. Heb

Dit is een andere HTTP-clientbibliotheek die wordt gebruikt voor het doen van aanvragen in Node-applicaties. Het werkt bijna hetzelfde als Axios, maar er zijn een paar verschillen in hoe ze werken. Het eerste is dat deze bibliotheek niet gebruikt kan worden aan de browser kant, dus aan de client kant. Het biedt een Stream en Pagination API out of the box. De Got-bibliotheek is een native ESM, wat betekent dat je de import moet gebruiken in plaats van CommonJS. Oh ja, het is ook een op Promise gebaseerde API.

Om Got met npm te installeren, voer je dit commando uit:


$ npm install got

Kijken naar een GET een verzoek met Got:


import got from 'got';

async function getUsers() {
  try {
   const response = await got.get('https://reqres.in/api/users').json();
    console.log(response.data);
  } catch (error) {
    console.error(error);
  }
}

getUsers()

Een POST-verzoek indienen is bijna net zo eenvoudig:


import got from 'got';

const data = {
  "name": "victor",
  "job": "writer"
}

async function addUser(data) {
  try {
   const response = await got.get('https://reqres.in/api/users', 
    {
      json: data
    }).json();
    console.log(response.data);
  } catch (error) {
    console.error(error);
  }
}

addUser()

Got aanpak is vergelijkbaar met Axios zoals ik eerder had gezegd, het enige verschil is de json() aan het einde. Dit geeft aan dat de gegevens in JSON zijn.

4. Node ophalen

Dit is een andere lichtgewicht HTTP-bibliotheek die net als de browser fetch API werkt. Hij is behoorlijk populair met meer dan 37 miljoen downloads in het NPM-register. In het ideale geval biedt het consistentie bij het werken met window.fetch in de browser, staat het het gebruik van native promises en async functies toe, verzoekannulering en heeft het nuttige uitbreidingen voor de limiet op de antwoordgrootte of de omleidingslimiet. 

Installeren met npm:


$ npm install node-fetch

Laten we daarmee een GET-verzoek doen aan onze api:


import fetch from 'node-fetch';

async function getUsers() {
    const response = await fetch('https://reqres.in/api/users');
    const data = await response.json();
    console.log(data);
}

getUsers()

Voor een POST-verzoek:


import fetch from 'node-fetch';


const data = {
  "name": "victor",
  "job": "writer"
}

async function addUser(data) {
    const response = await fetch('https://reqres.in/api/users', {
            method: 'post',
            body: JSON.stringify(data),
    });

    const data = await response.json();
    console.log(data);
}

addUser()

Werken met deze bibliotheek lijkt eigenlijk veel op de fetch API en er is een beetje werk dat je moet doen zoals .json() en .stringify() dat je moet doen op de gegevens. Meestal moet je ook zelf de headers instellen. 

5. SuperAgent

Deze bibliotheek is een VisionMedia-project met meer dan 29 miljoen downloads per maand. Het is een samenstelbare en op beloftes gebaseerde API die opnieuw probeert bij mislukking, redirects volgt, gzip afhandelt, een JSON-modus heeft en ook verzoeken kan annuleren. 

Je kunt SuperAgent met dit commando installeren: 


$ npm install superagent

Laten we een aanroep doen naar onze API met SuperAgent met de async functie:


const superagent = require('superagent');

async function getUsers() {
    try {
      const res = await superagent.get('https://reqres.in/api/users');
      console.log(res);
  } catch (err) {
      console.error(err);
  }
}

getUsers()

Dit lijkt bijna op Axios als je het je herinnert, vooral het antwoord dat je krijgt van de API. Het biedt ook een tekstveld samen met JSON. Omdat SuperAgent een op beloftes gebaseerde API is, moeten we een try/catch gebruiken om de fout af te handelen.

Gegevens naar de server sturen werkt ook prima, maar dan moet je .send() toevoegen:


const superagent = require('superagent');

const data = {
  "name": "victor",
  "job": "writer"
}

async function addUser(data) {
 try {
    const res = await superagent.post('https://reqres.in/api/users').send(data);
    console.log(res);
  } catch (err) {
    console.error(err);
  }
}

addUser()


const nocache = require('superagent-no-cache');
const superagent = require('superagent');
const prefix = require('superagent-prefix')('/static');

superagent
  .get('/some-url')
  .use(prefix) // Prefixes *only* this request
  .use(nocache) // Prevents caching of *only* this request
  .end((err, res) => {
    // Do something
  });

Fouten afhandelen

Het omgaan met fouten in HTTP verzoeken zal variëren naargelang de toepassing en zelfs de gebruikte client library, maar we moeten nog steeds rekening houden met sommige dingen in onze verzoeken. Bijvoorbeeld, als je een aanvraag doet naar een url, de verkeerde url eigenlijk met Axios, wat krijg je dan? Je krijgt een onbeheersbaar antwoord met een antwoordveld van ongedefinieerd. In dat geval kom je hier door een try/catch blok toe te voegen aan je code. Bijvoorbeeld:


async function talkToMe(reqBody) {
  try {
    let res = await Axios({
      method: 'post',
      url: 'https://api.com/to',
      data: reqBody
    });

    let data = res.data;
    return data;
  } catch (error) {
    console.log(error.response); 
    return error.response;
  }

}

Welke fout er ook optreedt in de try-sectie, deze wordt meteen opgevangen in de catch-sectie. Of als je met callbacks werkt, dan gebruik je de .catch() methode. De meeste bibliotheken bieden deze optie om fouten af te handelen.


axios.get('/user/:victor')
  .catch(function (error) {
    if (error.response) {
    ...
    ...

Er kunnen ook meer fouten optreden, zoals wanneer de site down is en je een 50X foutmelding krijgt. De meeste bibliotheken bieden deze optie om fouten af te handelen.

Conclusie

We hebben 5 manieren geprobeerd om HTTP-verzoeken te doen in Node en uit observaties blijkt dat ze in principe hetzelfde doen, maar dat sommige de bottleneck voor je afhandelen, met name Axios en SuperAgent. Maar dit is niet het artikel om je te vertellen welke beter is, maar om je alle gangbare manieren te laten zien en je de handigste te laten kiezen. 

Het belangrijkste doel van HTTP-verzoeken is om te communiceren tussen computers en er moet rekening worden gehouden met de methode, het doel en het protocol. Dus, doe je voordeel met dit artikel door de meest geschikte te kiezen voor jouw project.