lchrennew/es-fetch-api
Powerful extensible HTTP client for both node.js and browser.
npx skills add lchrennew/es-fetch-apiREADME
ES-Fetch-API
中文 | English
Very very very powerful, extensible http client for both node.js and browser.
AI Agent Support
This project provides built-in skills for AI agents (like Trae, Cursor, etc.) to understand and write code using es-fetch-api.
Installation
Run the following command in your project root to install the AI skills to .ai/skills and .agent/skills:
npx add-skill lchrennew/es-fetch-api
Why should you use ES-Fetch API?
Still using axios? ES-Fetch-API creates sunny world for you.
i. It's extremely light-weight and built on the native fetch API.
Comparing to axios which is ~400kB, es-fetch-api is just ~6kB. Because es-fetch-api is designed for native fetch API
compatible environments.
References:
ii. Enables maximized readability, extensibility, maintainability and minimized complexity.
1. The simplest example
Expected request:
GET http://yourdomain.com/api/v1/user?id=12345
Using axios:
import axios from 'axios'
// unneccessarily indicate that 'http://yourdomain.com/api/v1' means baseURL
const apiV1 = axios.create({ baseURL: 'http://yourdomain.com/api/v1' })
// unneccessarily indicate that `/user` means url
const getUser = id => apiV1.get({ url: `/user`, params: { id } })
const response = await getUser(12345)
Using es-fetch-api, great readability:
import { getApi } from "es-fetch-api";
import { query } from 'es-fetch-api/middelwares/query.js'
// without mincing words
const apiV1 = getApi('http://yourdomain.com/api/v1')
const getUser = id => apiV1(`user`, query({ id }))
const response = await getUser(12345)
2. More complicated example (using built-in middlewares)
Expected request:
POST http://yourdomain.com/api/v1/user/
Content-Type: application/json
{"firstName":"Fred","lastName":"Flintstone"}
Using axios:
import axios from 'axios'
const apiV1 = axios.create({ baseURL: 'http://yourdomain.com/api/v1' })
// which format is used to post data?
const createUser = user => apiV1.post(`/user`, user)
const resposne = await createUser({
firstName: 'Chun',
lastName: 'Li'
})
Using es-fetch-api, better readability:
import { getApi } from "es-fetch-api";
import { json } from 'es-fetch-api/middelwares/body.js'
import { POST } from 'es-fetch-api/middelwares/methods.js'
const apiV1 = getApi('http://yourdomain.com/api/v1')
// read what you see infomation losslessly
const createUser = user => apiV1(`user`, POST, json(user))
const resposne = await createUser({
firstName: 'Chun',
lastName: 'Li'
})
3. Create custom middleware to extend your code while keeping better readability.
Expected request:
POST http://yourdomain.com/api/v1/user/
Content-Type: application/json
Auhorization: Token ********
X-Timestamp: ##########
{"firstName":"Fred","lastName":"Flintstone"}
Using axios:
import axios from 'axios'
import { getToken } from 'token-helper'
// easy to read? it's hard to understand they return headers.
const useToken = async () => ({ 'Authorization': `Token ${await getToken()}` })
const useTimestamp = async () => ({ 'X-Timestamp': Date.now() })
const apiV1 = axios.create({ baseURL: 'http://yourdomain.com/api/v1' })
// easy to read? Maybe or not, but too long winded to maintain.
const createUser = async user => await apiV1.post({
url: `/user`,
data: user,
headers: { ...await useToken(), ...await useTimestamp() }
})
const resposne = await createUser({
firstName: 'Chun',
lastName: 'Li'
})
Using es-fetch-api, better readability, better maintainability:
import { getApi } from "es-fetch-api";
import { json } from 'es-fetch-api/middelwares/body.js'
import { POST } from 'es-fetch-api/middelwares/methods.js'
import { getToken } from 'token-helper'
// read what you see
const useToken = async (ctx, next) => {
ctx.header('Authoriza
...