Skip to content
main
Go to file
Code

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 
 
 
 
 
src
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

Helix Fetch Library

Library for making transparent HTTP/1(.1) and HTTP/2 requests.

helix-fetch is based on fetch-h2. helix-fetch in general adheres to the Fetch API Specification, implementing a subset of the API. However, there are some notable deviations:

  • Response.body is not implemented. Use Response.readable() instead.
  • Response.blob() is not implemented. Use Response.buffer() instead.
  • Response.formData() is not implemented.
  • The following fetch() options are ignored since helix-fetch doesn't have the concept of web pages: mode, referrer and referrerPolicy.

helix-fetch also supports the following extensions:

  • Response.buffer() returns a Node.js Buffer.

  • The body that can be sent in a Request can also be a Readable Node.js stream, a Buffer or a string.

  • fetch() has an extra option json that can be used instead of body to send an object that will be JSON stringified. The appropriate content-type will be set if it isn't already.

  • fetch() has an extra option timeout which is a timeout in milliseconds before the request should be aborted and the returned promise thereby rejected (with a TimeoutError).

    Deprecated: Use AbortController or timeoutSignal(ms) instead, see examples below.

  • The Response object has an extra property httpVersion which is either 1 or 2 (numbers), depending on what was negotiated with the server.

  • Response.headers.raw() returns the headers as a plain object.

Features

  • Fetch API implementation
  • Transparent handling of HTTP/1(.1) and HTTP/2 connections
  • Promise API/async & await
  • Streaming support
  • RFC 7234 compliant cache
  • HTTP/2 request and response multiplexing support
  • HTTP/2 Server Push support

Status

codecov CircleCI GitHub license GitHub issues LGTM Code Quality Grade: JavaScript Renovate enabled semantic-release

Installation

$ npm install @adobe/helix-fetch

Usage Examples

Access Response Headers and other Meta data

  const { fetch } = require('@adobe/helix-fetch');

  const resp = await fetch('https://httpbin.org/get');
  console.log(resp.ok);
  console.log(resp.status);
  console.log(resp.statusText);
  console.log(resp.method);
  console.log(resp.headers.raw());
  console.log(resp.headers.get('content-type'));

Fetch JSON

  const { fetch } = require('@adobe/helix-fetch');

  const resp = await fetch('https://httpbin.org/json');
  const jsonData = await resp.json();

Fetch text data

  const { fetch } = require('@adobe/helix-fetch');

  const resp = await fetch('https://httpbin.org/');
  const textData = await resp.text();

Fetch binary data

  const { fetch } = require('@adobe/helix-fetch');

  const resp = await fetch('https://httpbin.org//stream-bytes/65535');
  const imageData = await resp.buffer();

Specify a timeout for a fetch operation

Using signalTimeout(ms) extension:

  const { fetch, timeoutSignal, AbortError } = require('@adobe/helix-fetch');

  try {
    const resp = await fetch('https://httpbin.org/json', { signal: timeoutSignal(1000) });
    const jsonData = await resp.json();
  } catch (err) {
    if (err instanceof AbortError) {
      console.log('fetch timed out after 1s');
    }
  }

Using AbortController:

  const { fetch, AbortController, AbortError } = require('@adobe/helix-fetch');

  const controller = new AbortController();
  setTimeout(() => controller.abort(), 1000);

  try {
    const resp = await fetch('https://httpbin.org/json', { signal: controller.signal });
    const jsonData = await resp.json();
  } catch (err) {
    if (err instanceof AbortError) {
      console.log('fetch timed out after 1s');
    }
  }

Stream an image

  const fs = require('fs');
  const { fetch } = require('@adobe/helix-fetch');

  const resp = await fetch('https://httpbin.org/image/jpeg');
  (await resp.readable()).pipe(fs.createWriteStream('saved-image.jpg'));

Post JSON

  const { fetch } = require('@adobe/helix-fetch');

  const method = 'POST';
  const json = { foo: 'bar' };
  const resp = await fetch('https://httpbin.org/post', { method, json });

Post JPEG image

  const fs = require('fs');
  const { fetch } = require('@adobe/helix-fetch');

  const method = 'POST';
  const body = fs.createReadStream('some-image.jpg');
  const headers = { 'content-type': 'image/jpeg' };
  const resp = await fetch('https://httpbin.org/post', { method, body, headers });

Post form data

  const fs = require('fs');
  const { FormData, fetch } = require('@adobe/helix-fetch');

  const method = 'POST';
  const form = new FormData();
  form.append('foo', 'bar');
  form.append('data', [ 0x68, 0x65, 0x6c, 0x69, 0x78, 0x2d, 0x66, 0x65, 0x74, 0x63, 0x68 ]);
  form.append('some_file', fs.createReadStream('/foo/bar.jpg'), 'bar.jpg');
  const resp = await fetch('https://httpbin.org/post', { method, body: form });

GET with query parameters object

const { createUrl, fetch } = require('@adobe/helix-fetch');

const qs = {
  helix: 'dummy',
  foo: 'bar',
  rumple: "stiltskin",
};

const resp = await fetch(createUrl('https://httpbin.org/json', qs));

or using URLSearchParams:

const { fetch } = require('@adobe/helix-fetch');

const body = new URLSearchParams({
  helix: 'dummy',
  foo: 'bar',
  rumple: "stiltskin",
});

const resp = await fetch('https://httpbin.org/json', { body });

HTTP/2 Server Push

  const { fetch, onPush } = require('@adobe/helix-fetch');

  onPush((url) => console.log(`received server push: ${url}`));

  const resp = await fetch('https://nghttp2.org');
  console.log(`Http version: ${resp.httpVersion}`);

Customization

Set cache size limit (Default: 100 * 1024 * 1024 bytes, i.e. 100mb):

  const { fetch, cacheStats } = require('@adobe/helix-fetch').context({
    maxCacheSize: 100 * 1024, // 100kb
  });

  let resp = await fetch('http://httpbin.org/bytes/60000'); // ~60kb response
  resp = await fetch('http://httpbin.org/bytes/50000'); // ~50kb response
  console.log(cacheStats());

Force HTTP/1(.1) protocol:

  const { fetch } = require('@adobe/helix-fetch').context({
    httpsProtocols: ['http1'],
  });

  const resp = await fetch('https://nghttp2.org');
  console.log(`Http version: ${resp.httpVersion}`);

See Contexts for more options.

Misc

More example code can be found here.

Development

Build

$ npm install

Test

$ npm test

Lint

$ npm run lint
You can’t perform that action at this time.