well-known-components / interfaces

0 stars 2 forks source link

Proposal: minimal IFetchComponent interface #88

Open hugoArregui opened 5 months ago

hugoArregui commented 5 months ago

Currently, we depend on node-fetch to define the IFetchInterface, which is commonly used across WKC. I wanted to discuss the idea of keeping a minimal interface here and then extend this interface in the fetcher(s) package(s).

We could define something like:

import { URL, UrlObject } from 'url'

import { Readable } from 'stream'

export type Body = Readable & {
  text(): Promise<string>
  json(): Promise<unknown>
}

  export type HttpMethod = 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'CONNECT' | 'OPTIONS' | 'TRACE' | 'PATCH';

export type IFetchResponse = { statusCode: number; headers: Headers; body: Body }
export type Headers = Record<string, string | string[] | undefined>

export type IFetchComponent = {
  request(
    method: HttpMethod,
    url: string | URL | UrlObject,
    headers: Headers,
    body?: string | Buffer | Uint8Array | Readable | null
  ): Promise<IFetchResponse>
}

which is a contract simple enough to be implemented with undici or node-fetch or whatever, and perhaps the fetch package could define its own interface according to the underline implementation. Wdyt? @menduz @marianogoldman @aleortega

aleortega commented 5 months ago

I like the idea, also I would like to adapt the fetch from WKC to return this FetchResponse in case of error instead of throwing since we are seeing more use cases where that is needed to prevent re-work of handling.