UNPKG

@voiceflow/fetch

Version:

Voiceflow fetch wrapper and error handling for SDKs

175 lines (117 loc) 3.99 kB
# fetch Voiceflow fetch wrapper and error handling for SDKs ## Installation ```sh yarn add --exact @voiceflow/fetch @voiceflow/exception # if using for Node.JS yarn add --exact undici ``` ## Usage This is a universal library and can be used in the browser or in a Node.JS environment by passing a `fetch` implementation. ### Browser Usage ```ts import { FetchClient } from '@voiceflow/fetch'; const fetch = new FetchClient({ /* config */ }); ``` ### Node Usage Make sure to install `undici` when using in a Node.JS environment. ```sh yarn add --exact undici ``` ```ts import { FetchClient } from '@voiceflow/fetch/undici'; const fetch = new FetchClient({ /* config */ }); ``` ## Configuration - **`baseURL`** (`string`): this will be added as a prefix to the URL of all requests ## Features - [JSON requests](#json-requests) - [JSON responses](#json-responses) - [HTTP methods](#http-methods) - [throws on non-2xx](#throws-on-non-2xx) - [@voiceflow/exception integration](#voiceflowexception-integration) - [raw request passthrough](#raw-request-passthrough) ### JSON Requests Use the `json` option to pass a payload that will be serialized with `JSON.stringify`. This will also automatically add the request header `Content-Type: application/json`. ```ts const fetch = new FetchClient(); await fetch.put('http://example.com', { json: { foo: 'bar' }, }); ``` ### JSON Responses Use the `json()` method attached to the returned promise to resolve a parsed version of the response payload without needing an additional `await`. You can also specify a type for the parsed result, by default the type will be `unknown`. ```ts const fetch = new FetchClient(); const result = await fetch.get('http://example.com').json<{ id: number; name: string }>(); ``` ### HTTP Methods Use the appropriate method to set the HTTP method being used in the request. ```ts const fetch = new FetchClient(); fetch.delete('/foo'); // DELETE /foo fetch.get('/foo'); // GET /foo fetch.head('/foo'); // HEAD /foo fetch.patch('/foo'); // PATCH /foo fetch.post('/foo'); // POST /foo fetch.put('/foo'); // PUT /foo ``` ### Base URL Specify a base URL which should be used to build every request. ```ts const fetch = new FetchClient({ baseURL: 'http://example.com/' }); fetch.get('foo'); // GET http://example.com/foo ``` If you make a request using a `URL` instance then the `baseURL` option will be ignored. ```ts const fetch = new FetchClient({ baseURL: 'http://example.com/' }); const url = new URL('http://foo.com/bar'); fetch.get(url); // GET http://foo.com/bar ``` ### Throws on non-2xx If any non-`2xx` HTTP status is returned then a `ClientException` from `@voiceflow/exception` is thrown. ```ts const fetch = new FetchClient(); try { await fetch.get('http://example.com'); // return 404 } catch (err) { err; // ClientException } ``` ### `@voiceflow/exception` Integration Internal error codes and other error details are automatically extracted from the response payload when a non-`2xx` status is returned. ```ts import { ClientException } from '@voiceflow/exception'; const fetch = new FetchClient(); try { await fetch.get('http://example.com'); // return 404 } catch (err) { if (ClientException.instanceOf(err)) { err.errorCode; // ErrorCode | undefined } } ``` ### Raw Request Passthrough Use the `raw()` method to bypass all of the features above to access the underlying `fetch` interface directly. #### Browser Native `fetch` Request ```ts const fetch = new FetchClient(); const url = new URL('http://example.com'); const request = new Request(url); const response = await fetch.raw(request); // Response ``` #### Node.JS Native `undici.fetch` Request ```ts import { URL } from 'node:url'; import * as undici from 'undici'; const fetch = new FetchClient(undici.fetch); const url = new URL('http://example.com'); const request = new undici.Request(url); const response = await fetch.raw(request); // undici.Response ```