Furthermore, I am not sure about node-fetch or isomorphic-fetch, on Node.js
's side.
What is surprising about fetch
, is that it does not "raise-for-status" by default. Similarly, not sure about XMLHTTPRequest, where I rarely use it natively. See XMLHTTPRequest vs fetch.
Maybe a relatively safe way is to do it like this.
import deepMerge from './util'
export function createApi<
T extends Record<
string,
{
options: RequestInit
response: any
}
>
>({
validate = (r) => {
if (!r.ok) throw new Error(`${r.status}: ${r.statusText}`)
},
parse = (r) => r.json(),
options = {},
}: {
validate?: (r: Response) => void
parse?: (r: Response) => Promise<any>
options?: RequestInit
} = {}) {
return async <K extends keyof T>(
url: K,
opts: T[K]['options'] = {}
): Promise<T[K]['response']> => {
return fetch(url as string, deepMerge(options, opts)).then(async (r) => {
validate(r)
return parse(r)
.then((r) => {
if (r.error) throw new Error(r.error)
return r
})
})
}
}
Umm, I tried writing it, and it gets a little complex in TypeScript version...
Yes, this is not even accounting for AbortController...
Top comments (4)
Request is what I use, but that has been deprecated.
The Request team recommends either one from this list
github.com/request/request/issues/...
axios library is a common choice. It's a very small library for making requests. I find it's API a bit friendlier that native fetch
I actually resorted to
ky
. I would probably also useky-universal
orgot
, if I need to.fetch is just fine, I would prefer 'cross-fetch' for isomorphic use of fetch between frontend and node.js