Skip to content

Fetch based HTTP client with similar API to axios for browser and Node.js / 类似 Axios 语法的原生 fetch API 请求封装库

License

Notifications You must be signed in to change notification settings

dragon-fish/fexios

Repository files navigation

Fexios

类 Axios 语法的原生 fetch API 请求封装库
Fetch based HTTP client with similar API to axios for browser and Node.js

fetch + axios = fexios (Just a joke)

特色功能 Features

  • 🤯 Native fetch API (supports the Promise API)
  • 🤫 Method shortcuts (fexios.post())
  • 🔗 Hooks (intercept request and response)
  • 😏 Automatic transform request and response data
  • 😏 Automatic transforms for JSON data
  • 🤩 Instances with custom defaults
  • 🫡 Instance extendable
  • 😍 Fricking tiny size: index.umd.js 5.00 kB │ gzip: 2.13 kB │ map: 19.03 kB

安装 Installation

包管理器 Using package manager

# Node Package Manager
npm install fexios
# Why not pnpm
pnpm add fexios
# Or yarn?
yarn add fexios

Then import the library and enjoy:

import fexios, { createFexios, Fexios } from 'fexios'

// Using directly
fexios.get('https://zh.moegirl.org.cn/api.php')

// With options
const fexios = createFexios(/* options */)
const fexios = new Fexios(/* options */)
const fexios = Fexios.create(/* options */)

在浏览器中直接使用 Use directly in the browser

  • JS Module
import('https://unpkg.com/fexios?module').then(({ createFexios }) => {
  const fexios = createFexios(/* options */)
})
  • Global variables
<script src="https://unpkg.com/fexios"></script>

<script>
  // Using directly
  fexios.get('https://zh.moegirl.org.cn/api.php')

  // With options
  const { createFexios } = Fexios
  const fexios = createFexios(/* options */)
</script>

兼容性 Compatibility

Refer: https://developer.mozilla.org/docs/Web/API/Fetch_API

Chrome Edge Firefox Opera Safari Node.js
42 14 39 29 10.1 (iOS 10.3) ^16.15.0 || >=18.0.0

* Abort signal requires higher version.

使用方法 Usage

You can find some sample code snippets here.

new Fexios(configs: Partial<FexiosConfigs>)

FexiosConfigs
export type FexiosConfigs = {
  baseURL: string
  query: Record<string, string | number | boolean> | URLSearchParams
  headers: Record<string, string> | Headers
  credentials: 'omit' | 'same-origin' | 'include'
  responseType: 'json' | 'blob' | 'text'
}
Defaults
const DEFAULT_CONFIGS = {
  baseURL: '',
  credentials: 'same-origin',
  headers: {
    'content-type': 'application/json; charset=UTF-8',
  },
  query: {},
  responseType: 'json',
}

Fexios#request(config: FexiosRequestOptions)

fexios.request<T>(config): Promise<FexiosResponse<T>>

FexiosRequestOptions
export interface FexiosRequestOptions {
  baseURL?: string
  method?: FexiosMethods
  credentials?: 'omit' | 'same-origin' | 'include'
  headers?: Record<string, string> | Headers
  query?: Record<string, string | number | boolean> | URLSearchParams
  body?: Record<string, any> | string | FormData | URLSearchParams
  responseType?: 'json' | 'blob' | 'text'
}

returns {FexiosFinalContext}

export type FexiosFinalContext<T = any> = Omit<
  FexiosContext<T>,
  'rawResponse' | 'response' | 'data' | 'headers'
> & {
  rawResponse: Response
  response: FexiosResponse<T>
  headers: Headers
  data: T
}
export type FexiosResponse<T = any> = {
  rawResponse: Response
  ok: boolean
  status: number
  statusText: string
  headers: Headers
  isGood: boolean
  data: T
}

And common request methods aliases:

  • fexios.get(url[, config])
  • fexios.delete(url[, config])
  • fexios.head(url[, config])
  • fexios.options(url[, config])
  • fexios.post(url[, data[, config]])
  • fexios.put(url[, data[, config]])
  • fexios.patch(url[, data[, config]])

钩子 Hooks

You can modify context in hooks' callback then return it as a brand new context™.

Return false to abort request immediately.

export type FexiosHook<C = unknown> = (context: C) => AwaitAble<C | false>
export interface FexiosContext<T = any> extends FexiosRequestOptions {
  url: string // may changes after beforeInit
  rawRequest?: Request // provide in beforeRequest
  rawResponse?: Response // provide in afterRequest
  response?: FexiosResponse // provide in afterRequest
  data?: T // provide in afterRequest
}
Hooks example
const fexios = new Fexios()

fexios.on('beforeRequest', async (ctx) => {
  const url = new URL(ctx.url)
  if (url.searchParams.has('foo')) {
    return false
  } else {
    url.searchParams.set('foo', 'bar')
    ctx.url = '' + url
    return ctx
  }
})

beforeInit

All context passed as is. You can do custom conversions here.

beforeRequest

Pre-converted done.

At this time, ctx.url has been converted to final URL string. You cannot modify the ctx.query or ctx.baseURL to change ctx.url. Please modify ctx.url directly.

  • ctx.url {string} full URL string converted from url, baseURL and ctx.query
  • ctx.query {Record<string, string>} merged from url, requestOptions, baseOptions
  • ctx.headers {Record<string, string>} merged from requestOptions, baseOptions

afterBodyTransformed

JSON body has been transformed to JSON string. Content-Type header has been set to body's type.

  • ctx.body {string|URLSearchParams|FormData|Blob}

beforeActualFetch

The Request instance has been generated.

At this time, you cannot modify the ctx.url, ctx.query, ctx.headers or ctx.body (etc.) anymore. Unless you pass a brand new Request to replace ctx.rawRequest.

  • ctx.rawRequest {Request}

afterResponse

The FexiosFinalContext will be passed

interceptors

Oh, this is mimicked from axios. Just sweet sugar.

// They are the same
fexios.on('beforeRequest', async (ctx) => {})
fexios.interceptors.request.use((ctx) =>  {})

// Bro, they're just the same
fexios.on('afterResponse', async (ctx) => {})
fexios.interceptors.response.use((ctx) => {})

MIT License

Copyright (c) 2023 机智的小鱼君 (A.K.A. Dragon-Fish)

About

Fetch based HTTP client with similar API to axios for browser and Node.js / 类似 Axios 语法的原生 fetch API 请求封装库

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published