Skip to content

Svelte custom fetch #1125

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
ESchouten opened this issue May 9, 2023 · 9 comments · Fixed by #1311
Closed

Svelte custom fetch #1125

ESchouten opened this issue May 9, 2023 · 9 comments · Fixed by #1311
Labels
docs Requires an update to docs enhancement New feature or request openapi-fetch Relevant to the openapi-fetch library PRs welcome PRs are welcome to solve this issue!

Comments

@ESchouten
Copy link

Svelte provides a custom fetch in their load functions which you have to use in order to use SSR and their middleware handlers.
For this library Svelte is listed as supported, but I can't figure out how this Svelte fetch is used. Are there examples? Or is this underway?

@ESchouten ESchouten added enhancement New feature or request PRs welcome PRs are welcome to solve this issue! labels May 9, 2023
@drwpow
Copy link
Contributor

drwpow commented May 9, 2023

This is a great idea! I’m actually working on building out more of a docs site right now, and framework-specific examples should definitely be added.

@drwpow
Copy link
Contributor

drwpow commented May 9, 2023

But also there probably are some caveats with language-specific things. For example, in React/React Router, there are loaders that can be used to load data on route change (which can be handy for things like auth), however, this is incompatible with openapi-fetch because there’s no way to maintain the type inference through the entire React Router layer (same goes for a typed GraphQL wrapper, or anything else, for that matter).

But again, it would still help to have framework examples along with notes about what does/doesn’t work well for each framework (but as a general rule, openapi-fetch will probably work the exact same way a typed GraphQL client will)

@drwpow
Copy link
Contributor

drwpow commented May 22, 2023

drwpow/openapi-fetch#51 partially handles this by allowing you to override the default global fetch method called (useful for Node / server-side-based things). But writing an example would still be helpful (I am planning on writing this myself, but if someone has already experimented with this themselves and has a good pattern, I’d love a PR!).

@drwpow
Copy link
Contributor

drwpow commented May 22, 2023

Edit: I’ve just transferred the issue (just learned you could do that!).

@drwpow drwpow closed this as completed May 22, 2023
@drwpow drwpow transferred this issue from drwpow/openapi-fetch May 22, 2023
@drwpow drwpow reopened this May 22, 2023
@drwpow drwpow added openapi-fetch Relevant to the openapi-fetch library docs Requires an update to docs labels May 22, 2023
@pkb-pmj
Copy link

pkb-pmj commented Aug 11, 2023

It's currently not possible to pass fetch to a single request like this

const { response } = await POST("/auth/login", {
    body: form.data,
    fetch,
});

And it seems necessary, because the fetch provided by SvelteKit inherits e.g. request-specific cookies.
Or is there some other way to use it which I have not thought of? If not, I can make a PR basically right now 😄

@ESchouten
Copy link
Author

ESchouten commented Aug 11, 2023

@pkb-pmj I have not used this library (yet), but I guess you could do

createClient<paths>({ baseUrl: "https://myapi.dev/v1/", fetch })

in your load function and create a client everywhere you want to fetch?

@pkb-pmj
Copy link

pkb-pmj commented Aug 11, 2023

I can also do it e.g. in hooks.server.ts:

export const handle = async ({ event, resolve }) => {
    const client = createClient<paths>({
        fetch: event.fetch,
        baseUrl: "/api",
    });
    event.locals.GET = client.GET;
    event.locals.PATCH = client.PATCH;
    event.locals.POST = client.POST;
    event.locals.PUT = client.PUT;

    return await resolve(event);
};

But I guess I don't want to create a new client on every request, when it's very easy to modify the client to accept custom per-request fetch.

@drwpow
Copy link
Contributor

drwpow commented Aug 19, 2023

Added an example to the docs that uses the custom fetcher.

To @pkb-pmj’s suggestion of putting in hooks.server.ts I didn’t add to the example because I’m still not too familiar on that “magic” in order to recommend that. But PRs are welcome if you’d like to add it 🙂

I guess I don't want to create a new client on every request

In most instances, yes, that’d probably be a concern. But I recently added benchmarks and the createClient() setup is extremely lightweight (it basically only saves your headers and settings into an persistent object—it’s not doing any major setup or anything). I profiled it at 2.5M ops/s on my machine. So yes as a general rule probably best to never do work you don’t need to. But also, if it makes your life easier for whatever reason, calling createClient() every request won’t have any practical impacts.

@pkb-pmj
Copy link

pkb-pmj commented Aug 20, 2023

@drwpow ok, I didn't think of that lol

const client = createServerClient(fetch);
const fact = await client.GET("/fact", {
  params: {
    query: { max_length: 500 },
  },
});

Not much different than using locals (ignoring creating the client in handle and declaring Locals type in app.d.ts):

const fact = await locals.GET("/fact", {
  params: {
    query: { max_length: 500 },
  },
});

Or my custom version:

const fact = await GET("/fact", {
  fetch,
  params: {
    query: { max_length: 500 },
  },
});

which is objectively better in a way that realistically doesn't matter as you said, so it's a question of preference?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Requires an update to docs enhancement New feature or request openapi-fetch Relevant to the openapi-fetch library PRs welcome PRs are welcome to solve this issue!
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants