npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

solid-fetch

v3.0.6

Published

Http request client promise-based supporting injectable request properties like: headers, parameters, query, body, etc.

Downloads

36

Readme

Solid-Fetch

SolidFetch is created with one goal in mind, to make client-server-requests as easy as possible. These means: less code, less headache and more power over the communication channel.

Core tools

Supporting injectable request properties in url, parameters, search-query, headers and body. Supporting intercepting requests, responses and errors to easily control and maintain communication with servers.

Install

yarn add solid-fetch

or:

npm install solid-fetch

Usage

Since node v18 fetch is supported with no extra effort so the native fetch function will be used on both browser and node.

import SolidFetch from 'solid-fetch'

const SolidFetchClient = new SolidFetch()

SolidFetchClient.request`http://test-server.io/messages`()
  .then((res) => {
    console.log('result from SolidFetch')
  })
  .catch((err) => {
    console.log('error from SolidFetch')
  })

Config Props

| Prop | Type | Default | Description | |----------------|-----------|---------|-------------------------| | initInjectables| Object | {} | The props the api-client can inject into the request properties: url, headers, etc. | | globalHeaders | Object | {} | Global headers to be injected to all requests | | globalQuery | Object | {} | Global search-query params to be injected to all requests | | interceptedReq | Array | [] | Array of interceptors to run before request is sent | | interceptedRes | Array | [] | Array of interceptors to run after response is received | | interceptedErr | Array | [] | Array of interceptors to run after error is received |

Set Injectables

SolidFetch comes very handy when you have plenty of dynamic props that needs to create the request. Using SolidFetch you can give the module pieces of data that you would like to use later, ex. access-token, language or user-id.

The example shows the injectables being set at one spot, but you can set them as many times as you want from where ever you need. Also by setting the two objects will be merged, only former existing fields will be overwritten.

import SolidFetch from 'solid-fetch'

const SolidFetchClient = new SolidFetch()

SolidFetchClient.setInjectables({
  language: 'de',
  userId: '123',
  jwtToken: () => dataStore.getState().jwtToken
})

Consume Injections in Request

After setting the injectables you can just refer to it during the request construction since the module is already aware of it.

import SolidFetch from 'solid-fetch'

// Injection in URL
SolidFetch.request`http://test-server.io/${(p) => p.language}/messages`({
  query: {
    // Injection in search-query
    language: (p) => p.language
  }
  headers: {
    // Injection in headers
    Authorization: (p) => `Bearer ${p.jwtToken}`
  },
  body: (p) => ({
    // Injection in body
    userId: p.userId
  })
})
  .then((res) => {
    console.log('result from SolidFetch')
  })
  .catch((err) => {
    console.log('error from SolidFetch')
  })

Note: Body, Query, Headers can be resolved in two ways

  • Less intuitive but fits for object with nested keys:
SolidFetch.request`url`({
  body: (p) => ({
    // Injection in body
    userId: p.userId
  })
})
  • Similar to the other injections but works only with first level keys:
SolidFetch.request`url`({
  body: {
    // Injection in body
    userId: (p) => p.userId
  }
})

Typescript Support

Types for the injectables are partially supported.


import SolidFetch from 'solid-fetch'

interface Injectables {
  apiUrl
}

const SolidFetchClient = new SolidFetch<Injectables>()

SolidFetchClient.request`${(p) => p.apiUrl}/messages`()
  .then((res) => {
    console.log('result from SolidFetch')
  })
  .catch((err) => {
    console.log('error from SolidFetch')
  })

* p will be correctly typed and will offer apiUrl as auto complete

Global Injections

Same like injectables per a request, you can set to all requests globally added values on headers and search-query. They will be added to the request without further code. The header or search-query can be overwritten per specific request by giving the prop with a different value.

import SolidFetch from 'solid-fetch'

SolidFetch.setConfig({
  globalHeaders: {
    Authorization: (p) => `Bearer ${p.jwtToken}`
  }
})

SolidFetch.request`http://test-server.io/${p => p.language}/messages`({
  query: {
    language: p => p.language
  }
  // No need to set Authorization header since it will be added to all requests
})
  .then((res) => {
    console.log('result from SolidFetch')
  })
  .catch((err) => {
    console.log('error from SolidFetch')
  })

Using with Typescript (Injectables & Response)

Typescript is supported as well. Injectables can be typed to have autocompletion. Requests can receive a type to have typed response. Note the type will be present on the data prop of the response.

import SolidFetch from 'solid-fetch'

interface Injectables {
  baseUrl: string
  userId: string
  jwtToken: () => string
}

const SolidFetchClient = new SolidFetch<Injectables>({
  initInjectables: {
    baseUrl: 'http://test-server.io',
    userId: '123',
    jwtToken: () => dataStore.getState().jwtToken
  }
})

const res = await SolidFetchClient.request<string>`${p => p.baseUrl}/messages`()

Interceptions

SolidFetch gives the ability to intercept all outgoing and incoming communication. That can be useful for error logging, caching, usage-statistics, etc.

Interceptor is an object which must have an action property, it is recommended to add name or any other identifier to the interceptor for further references. Interceptor action can mutate the current value of the action or just to cause side-effects.

Since you might want to run more than one interception, interceptions are stored in arrays and will be executed in sequence. If nothing returned from the interceptor, the next interceptor will run on the last generated value. The interceptors are reduce functions that will in the end have a similar structure to the data needed.

Request Interception

import SolidFetch from 'solid-fetch'

SolidFetch.setConfig({
  interceptedReq: [{
    name: 'debugging',
    action: (request) => {
      console.log('caught a request')
      console.log({ request })
    },
  }],
})

Response Interception

Response interceptors will get the result of the request after processing. Means, only if it has status of 200, also if it is application/json then the parsed json will be given, otherwise just the raw response value.

import SolidFetch from 'solid-fetch'

SolidFetch.setConfig({
  interceptedRes: [{
    name: 'debugging',
    action: (result) => {
      console.log('caught a response')
      statisticService.post(result)
    },
  }],
})

Error Interception

Error interceptors will get the error data of the request.

import SolidFetch from 'solid-fetch'

SolidFetch.setConfig({
  interceptedErr: [{
    name: 'error-tracer',
    action: (error) => {
      console.log('caught a response')
      errorTracer.postError(error)
    },
  }],
})

*If the status code is NOT 200-299, an error will be thrown.

Request, Response, Error Shape

Request:

{
  url: String,
  requestOptions: {
    method: String = 'GET',
    headers: Object = {},
    query: Object = {},
    body: String,
  }
}

Response:

{
  data: <ParsedResult> || <RawResponse>,
  headers: Object,
  ok: Boolean,
  redirected: Boolean,
  size: Number,
  status: Number,
  statusText: String,
  request: {
    url: String,
    requestOptions: {
      method: String = 'GET',
      headers: Object = {},
      query: Object = {},
      body: String,
    }
  }
}

Standard JS Error with JSON content:

{
  name: String,
  description: String,
  response: <RawResponse>, // optional
  request: {
    url: String,
    requestOptions: {
      method: String = 'GET',
      headers: Object = {},
      query: Object = {},
      body: String,
    }
  }
}

Advanced

Use your solid-fetch configs outside of it

import SolidFetchClient from './your-solid-fetch-client'

const { useId, jwtToken } = SolidFetchClient.getInjectables()