Skip to content

Instantly share code, notes, and snippets.

@roboncode
Last active June 5, 2024 23:52
Show Gist options
  • Save roboncode/7f5d4c41bb1a337762624d626b9b4aaf to your computer and use it in GitHub Desktop.
Save roboncode/7f5d4c41bb1a337762624d626b9b4aaf to your computer and use it in GitHub Desktop.
Lightweight Axios replacement using Fetch
class Client {
static _instance
static defaultHeaders = { 'Content-Type': 'application/json' }
config = {
baseUrl: '',
urlHandler: (baseUrl, uri, query) => {
var url = `${baseUrl}${uri}`
if (uri.includes('://')) {
url = uri
}
const queryParams = this._queryParamsToString(query)
if (queryParams) {
return `${url}?${queryParams}`
}
return url
},
requestHandler: request => {
return request
},
responseHandler: response => {
return response.text().then(text => {
const data = text && JSON.parse(text)
if (!response.ok) {
const error = (data && data.message) || response.statusText
return Promise.reject(error)
}
return { data }
})
},
}
_queryParamsToString(params) {
const urlParams = new URLSearchParams()
for (let k in params) {
urlParams.append(k, params[k])
}
return urlParams.toString()
}
constructor(config) {
Object.assign(this.config, config || {})
}
async get(uri, query) {
const url = this.config.urlHandler(this.config.baseUrl, uri, query)
const request = await this.config.requestHandler({
method: 'GET',
mode: 'cors',
cache: 'no-cache',
headers: {
...this.defaultHeaders,
Authorization: Client.getAuth(),
},
})
return fetch(url, request).then(
this.config.responseHandler
)
}
async post(uri, body, query) {
const url = this.config.urlHandler(this.config.baseUrl, uri, query)
const request = await this.config.requestHandler({
method: 'POST',
mode: 'cors',
cache: 'no-cache',
headers: {
...Client.defaultHeaders,
},
body: JSON.stringify(body),
})
return fetch(url, request).then(
this.config.responseHandler
)
}
async put(uri, body, query) {
const url = this.config.urlHandler(this.config.baseUrl, uri, query)
const request = await this.config.requestHandler({
method: 'PUT',
mode: 'cors',
cache: 'no-cache',
headers: {
...this.defaultHeaders,
Authorization: Client.getAuth(),
},
body: JSON.stringify(body),
})
return fetch(url, request).then(
this.config.responseHandler
)
}
async patch(uri, body, query) {
const url = this.config.urlHandler(this.config.baseUrl, uri, query)
const request = await this.config.requestHandler({
method: 'PATCH',
mode: 'cors',
cache: 'no-cache',
headers: {
...this.defaultHeaders,
Authorization: Client.getAuth(),
},
body: JSON.stringify(body),
})
return fetch(url, request).then(
this.config.responseHandler
)
}
async delete(uri, query) {
const url = this.config.urlHandler(this.config.baseUrl, uri, query)
const request = await this.config.requestHandler({
method: 'DELETE',
mode: 'cors',
cache: 'no-cache',
headers: {
...this.defaultHeaders,
Authorization: Client.getAuth(),
},
})
return fetch(url, request).then(
this.config.responseHandler
)
}
static instance(config) {
if (!this._instance) {
this._instance = new Client(config)
}
return this._instance
}
static create(config) {
return new Client(config)
}
}
@suhaotian
Copy link

Cool, very liteweight!

I implemented one too, support nested object, interceptors and a lot plugins, already fixed some axios compatible issues from users feedback.

If you interested can check here: https://github.com/suhaotian/xior

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment