Skip to content

Instantly share code, notes, and snippets.

@Victor1890
Created December 27, 2023 22:51
Show Gist options
  • Save Victor1890/0a7bbe2efb1b6aad216a1698f68d7348 to your computer and use it in GitHub Desktop.
Save Victor1890/0a7bbe2efb1b6aad216a1698f68d7348 to your computer and use it in GitHub Desktop.
This TypeScript class, named Base, is designed to be extended by other classes, serving as a solid foundation for building HTTP clients in TypeScript applications. It leverages the Fetch API to simplify common HTTP operations, including GET, POST, PATCH, and DELETE requests. The class provides a clean and extensible interface for making API call…
class Base {
private readonly api: string
private readonly headers: HeadersInit
constructor(api: string, headers: HeadersInit = {}) {
this.api = api
this.headers = headers
}
private params(params: Record<string, any>): string {
return Object.keys(params)
.map((key) => {
let value = params[key]
value = typeof value == typeof {} ? JSON.stringify(value) : value
return `${key}=${value}`
})
.join('&')
}
private async getMessage(response: Response): Promise<string> {
const data = await response.json()
const conditionError = data && data.error
const conditionWithMessage = data && data.message
if (conditionWithMessage) return data.message
if (conditionError) return data.error.message
return `${response.statusText}`
}
protected async get<T = unknown>(
url: string,
params: Record<string, any> = {},
headers: HeadersInit = {}
): Promise<T> {
const _isParam = Object.keys(params).length > 0
const response = await fetch(`${this.api}${url}${_isParam ? `?${this.params(params)}` : ''}`, {
headers: { ...this.headers, ...headers },
})
if (!response.ok) {
throw new Error(await this.getMessage(response))
}
return response.json()
}
protected async post<T = unknown>(url: string, data: Record<string, any> = {}): Promise<T> {
const response = await fetch(`${this.api}${url}`, {
method: 'POST',
headers: this.headers,
body: JSON.stringify(data),
})
if (!response.ok) {
throw new Error(await this.getMessage(response))
}
return response.json()
}
protected async update<T = unknown>(url: string, data: Record<string, any> = {}): Promise<T> {
const response = await fetch(`${this.api}${url}`, {
method: 'PATCH',
headers: this.headers,
body: JSON.stringify(data),
})
if (!response.ok) {
throw new Error(await this.getMessage(response))
}
return response.json()
}
protected async delete<T = unknown>(url: string): Promise<T> {
const response = await fetch(`${this.api}${url}`, {
method: 'DELETE',
headers: this.headers,
})
if (!response.ok) {
throw new Error(await this.getMessage(response))
}
return response.json()
}
}
export default Base
@Victor1890
Copy link
Author

For example:

class AuthProvider extends Base {
    constructor() {
        super('url', {
            'Content-Type': 'application/json'
        });
    }

    public login(username: string, password: string) {
        return this.post<{ login: boolean }>('/login',  { username, password });
    }
}

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