@krutoo/fetch-tools@0.1.1Built and signed on GitHub ActionsBuilt and signed on GitHub Actions
A set of useful utils for JavaScript Fetch API
Fetch tools
Set of utilities for JavaScript Fetch API.
Goals
- do not change
fetch
behavior, just add some features - ability to run in browser, Node.js, Deno, Bun, WinterJS (...any runtime that implements Fetch API)
- zero dependencies
Installation
# in Node.js via NPM npm add @krutoo/fetch-tools # in Deno via JSR deno add @krutoo/fetch-tools # in Bun bun add @krutoo/fetch-tools
Usage
Creating fetch with some extra features.
import { applyMiddleware, configureFetch } from '@krutoo/fetch-tools'; import { defaultHeaders, log, validateStatus } from '@krutoo/fetch-tools/middleware'; // configure your own fetch... const myFetch = configureFetch( fetch, applyMiddleware( // validate status (like in axios) validateStatus((status) => status >= 200 && status < 300), // add default headers defaultHeaders({ 'user-agent': 'test', }), // log request stages (before request, after response, on catch) log({ onCatch: ({ error }) => console.error(error), }), ), ); // ...and using it like normal fetch myFetch('posts/1') .then((res) => res.json()) .then((data) => console.log(data));
Middleware
Middleware are just functions and you can write your own.
async function myMiddleware(request, next) { try { // [do something before request here] const response = await next(request); // [do something after response here] return response; } catch (error) { // [do something on error here but don't forget throw error or return response] throw error; } }
Builtin middleware
validateStatus
Returns a middleware that will validate status.
import { applyMiddleware, configureFetch } from '@krutoo/fetch-tools'; import { validateStatus } from '@krutoo/fetch-tools/middleware'; const myFetch = configureFetch( fetch, applyMiddleware( // fetch promise will be rejected when status is not valid validateStatus((status) => status >= 200 && status < 300), ), );
defaultHeaders
Returns a middleware that will set default headers to request.
import { applyMiddleware, configureFetch } from '@krutoo/fetch-tools'; import { defaultHeaders } from '@krutoo/fetch-tools/middleware'; const myFetch = configureFetch( fetch, applyMiddleware( // all requests will contain declared headers defaultHeaders({ 'user-agent': 'spy' }), ), );
log
Returns a middleware that will log phases by handler.
import { applyMiddleware, configureFetch } from '@krutoo/fetch-tools'; import { log } from '@krutoo/fetch-tools/middleware'; const myFetch = configureFetch( fetch, applyMiddleware( // each phase of request will be logged log({ onRequest({ request }) { console.log(request); }, onResponse({ request, response }) { console.log(response); }, onCatch({ request, error }) { console.error(error); }, }), ), );
jwt
Returns simplest JWT middleware. This middleware will add Authorization
header to each request
that matches the condition.
import { applyMiddleware, configureFetch } from '@krutoo/fetch-tools'; import { jwt } from '@krutoo/fetch-tools/middleware'; const myFetch = configureFetch( fetch, applyMiddleware( jwt({ // Access token token: '...', // Determines whether to add a header filter: (req) => req.url.includes('/api/'), }), // ...or like this jwt({ // "token" can be function that should return string or null or Promise<string | null> token: () => getJwtFromSomewhere(), }), ), );
retry
Returns a middleware that will retry the request until either:
- or the retries count is exceeded;
- or until a successful response is received.
import { applyMiddleware, configureFetch } from '@krutoo/fetch-tools'; import { retry } from '@krutoo/fetch-tools/middleware'; const myFetch = configureFetch( fetch, applyMiddleware( retry({ count: 5, whenNotOk: true, whenCatch: false, }), ), );
proxy
Returns simple proxy middleware. Useful for servers based on Fetch API.
import { applyMiddleware } from '@krutoo/fetch-tools'; import { proxy } from '@krutoo/fetch-tools/middleware'; const enhance = applyMiddleware( proxy({ // pathname(s) of incoming request URL which will be proxied filter: ['/api/v2/', '/api/v3/'], // define target URL target: 'https://www.my-site.com/', }), ); Deno.serve( enhance((req) => { return new Response('<h1>Main page</h1>'); }), );
Server utilities
You can use utils for simply configure your HTTP server.
In Deno
import { router } from '@krutoo/fetch-tools/server'; const handler = router .builder() .get('/', () => new Response('Home page')) .put('/about', () => new Response('About page')) .post('/news', () => new Response('News page')) .all('/stats', () => new Response('Some stats')) .build(); await Deno.serve({ port: 8080, handler: handler, });
In Bun
import { router } from '@krutoo/fetch-tools/server'; const handler = router .builder() .get('/', () => new Response('Home page')) .put('/about', () => new Response('About page')) .post('/news', () => new Response('News page')) .all('/stats', () => new Response('Some stats')) .build(); Bun.serve({ port: 8080, fetch: handler, });
In Node.js (node:http
or express
)
Currently there is no builtin server implementation based on Fetch API in Node.js.
It is possible to use adapter for node:http
or express
from
@whatwg-node/server.
import { router } from '@krutoo/fetch-tools'; import { createServer } from 'node:http'; import { createServerAdapter } from '@whatwg-node/server'; const handler = router .builder() .get('/', () => new Response('Home page')) .put('/about', () => new Response('About page')) .post('/news', () => new Response('News page')) .all('/stats', () => new Response('Some stats')) .build(); const server = createServer(createServerAdapter(handler)); server.listen(8080);
Middleware for servers
You can use middleware for server handlers too:
import { applyMiddleware } from '@krutoo/fetch-tools'; import { router } from '@krutoo/fetch-tools/server'; import { log } from '@krutoo/fetch-tools/middleware'; const enhance = applyMiddleware( log({ onCatch: ({ error }) => console.error(error), }), ); const handler = router .builder() .get('/', () => new Response('Home page')) .put('/about', () => new Response('About page')) .post('/news', () => new Response('News page')) .all('/stats', () => new Response('Some stats')) .build(); Bun.serve({ port: 8080, fetch: enhance(handler), // just wrap handler to enhancer for apply middleware });
Working with HTTP cookie on server
Cookies can be used in different ways on the server.
Browser like behavior
If you want to imitate browser behavior as much as possible in terms of working with cookies, you
can use @krutoo/fetch-tools
together with fetch-cookie
.
To use fetch-cookie as an middleware, follow these instructions.
Microfrontends
Server part of the microfrontend can make requests to some HTTP API on behalf of the user, sending his cookies in requests.
In this case you can use just defaultHeaders
middleware:
import { applyMiddleware, configureFetch } from '@krutoo/fetch-tools'; import { defaultHeaders } from '@krutoo/fetch-tools/middleware'; // example of server handler async function handler(request: Request) { const myFetch = configureFetch( fetch, applyMiddleware( // forward cookie from incoming request to all outgoing requests defaultHeaders({ cookie: request.headers.get('cookie') }), ), ); // this request will contain cookies from the incoming request const orders = await myFetch('http://something.com/api/user/orders').then( (res) => res.json(), ); return new Response(JSON.stringify({ orders }), { 'content-type': 'application/json', }); }
To do
JWT middlewareretry middlewareability to use with Bun'sBun.serve
and Deno'sserve
fromstd/http
Add Package
deno add jsr:@krutoo/fetch-tools
Import symbol
import * as fetch_tools from "@krutoo/fetch-tools";
Import directly with a jsr specifier
import * as fetch_tools from "jsr:@krutoo/fetch-tools";
Add Package
pnpm i jsr:@krutoo/fetch-tools
pnpm dlx jsr add @krutoo/fetch-tools
Import symbol
import * as fetch_tools from "@krutoo/fetch-tools";
Add Package
yarn add jsr:@krutoo/fetch-tools
yarn dlx jsr add @krutoo/fetch-tools
Import symbol
import * as fetch_tools from "@krutoo/fetch-tools";
Add Package
vlt install jsr:@krutoo/fetch-tools
Import symbol
import * as fetch_tools from "@krutoo/fetch-tools";
Add Package
npx jsr add @krutoo/fetch-tools
Import symbol
import * as fetch_tools from "@krutoo/fetch-tools";
Add Package
bunx jsr add @krutoo/fetch-tools
Import symbol
import * as fetch_tools from "@krutoo/fetch-tools";