openapi-ts / openapi-typescript

Generate TypeScript types from OpenAPI 3 specs
https://openapi-ts.dev
MIT License
5.1k stars 410 forks source link

Custom fetch function from Nuxt fails #1691

Open Siilwyn opened 1 month ago

Siilwyn commented 1 month ago

Description Hi! Unsure if this is the right place but figured I'll have to start somewhere. I'm trying to pass a custom fetch function, useRequestFetch, so that cookies are passed (https://github.com/nuxt/nuxt/issues/24813).

Reproduction Using openapi-fetch@0.9.7 and openapi-typescript@6.7.6, with nuxt@3.11.2, I create a client:

  const client = createClient<paths>({
    baseUrl: String(new URL('/api/qne/', baseUrl)),
    fetch: useRequestFetch(),
  });

Then doing a request (tried GET & POST) results in:

[GET] "http://localhost:3000/api/proxy-api/": <no response> Failed to parse URL from [object Request]
  at async $fetchRaw2 (node_modules/ofetch/dist/shared/ofetch.37386b05.mjs:231:14)
  at async $fetch2 (node_modules/ofetch/dist/shared/ofetch.37386b05.mjs:268:15)
  at async coreFetch (node_modules/openapi-fetch/dist/index.js:101:20)
  at async setup (src/pages/test.vue:23:19)

I get the same result using $fetch as the fetch function. Under the hood ofetch is used, is the API just incompatible? Though I would expect $fetch.raw to work but it returns the same error.

Checklist

scripness commented 1 month ago

I am also looking for a solution to integrate this with $fetch and useFetch, have you got any progress?

Siilwyn commented 1 month ago

@scripness nope, I am looking into using fetch instead of the openapi-fetch client and passing types manually though.

HerrBertling commented 1 month ago

I ran into this today with using Remix, so this is apparently not exclusive for NuxtJS 😄

scripness commented 1 month ago

If not possible to integrate with their fetches I would love to have a guide on how to manually type their fetches to match this library.

drwpow commented 3 weeks ago

To add middleware support in 0.9.0 this library internally switched from fetch(url, init) to fetch(new Request()) so the full Request could be passed (and modified) through middleware.

The latter API is somewhat less-common, but nonetheless valid and part of the spec.

However we have been getting more reports of related errors due to this, likely because fetch(url, init) is a more likely API. Taking a look at ofetch, it seems like it’s not a spec-compliant fetch replacement because it doesn’t seem to support fetch(new Request()) as an API (or, at least, it’s not in the tests, so if it is supported it’s not catching regressions).

There are some other middleware improvements that have been suggested, and it’s not a hard requirement that new Request() be used in every request and passed along to the custom fetch. We can probably make some internal changes that fix this issue without too much disruption (but just for safety, will release this in 0.10.0 since in the pre-1.0 releases, minor versions may contain breaking changes.

scripness commented 3 weeks ago

To add middleware support in 0.9.0 this library internally switched from fetch(url, init) to fetch(new Request()) so the full Request could be passed (and modified) through middleware.

The latter API is somewhat less-common, but nonetheless valid and part of the spec.

However we have been getting more reports of related errors due to this, likely because fetch(url, init) is a more likely API. Taking a look at ofetch, it seems like it’s not a spec-compliant fetch replacement because it doesn’t seem to support fetch(new Request()) as an API (or, at least, it’s not in the tests, so if it is supported it’s not catching regressions).

There are some other middleware improvements that have been suggested, and it’s not a hard requirement that new Request() be used in every request and passed along to the custom fetch. We can probably make some internal changes that fix this issue without too much disruption (but just for safety, will release this in 0.10.0 since in the pre-1.0 releases, minor versions may contain breaking changes.

Hey! Thank you, it would be great to your (or someone else's) ability to make one way or another an example of how to use openapi-fetch with nuxt's server side fetch or how to type their fetch functions in such a way that it behaves similar to openapi-fetch 😊

drwpow commented 3 weeks ago

To follow up on this, it seems for now we will have to stick with the fetch(new Request()) API to support middleware. Otherwise this library incurs quite a bit of overhead, bloat, and performance hit that I would like to omit. I hate to say “this is an upstream issue with ofetch” … but that’s what it is 😅. ofetch does not implement the fetch spec, which means by decisions they’ve made it is incompatible with some fetch wrappers (which I guess that means the current version of openapi-fetch).

It’s probably worth raising an issue on ofetch to support the fetch(new Request()) API in the interest of spec compliance and see what the maintainers say.