orval-labs / orval

orval is able to generate client with appropriate type-signatures (TypeScript) from any valid OpenAPI v3 or Swagger v2 specification, either in yaml or json formats. 🍺
https://orval.dev
MIT License
2.8k stars 311 forks source link

Svelte: SvelteKit and SSR #776

Open Gustutu opened 1 year ago

Gustutu commented 1 year ago

First of all, thanks @anymaniax for this awesome tool.

I am trying to integrate orval in my sveltekit project, it doesn't seem to be so easy. Does the following page of tanstack : https://tanstack.com/query/latest/docs/svelte/ssr apply to orval and how to solve this problem in orval ?

anymaniax commented 1 year ago

Hello @Gustutu, just added the compatibility with the new tanstack svelte query in the last version. So everything should work as expected. And yes you need to do the setup as explained in the doc. Don’t hesitate to open an issue if you find any problem with it

Gustutu commented 1 year ago

Thanks, i'll try that.

Gustutu commented 1 year ago

I 'm not sure to understand everything, It seems to work but about the following section : https://tanstack.com/query/v4/docs/svelte/ssr#using-prefetchquery, it advice to use the prefetchQuery is it possible to do is with orval, is it necessary ?

anymaniax commented 1 year ago

@Gustutu Yes sure

Gustutu commented 1 year ago

Ok i think i finally understood, orval generate basic function to make api call and also generate way to use the query from tanstack. And you can choose wich one to use in your code depending on your needs.

anymaniax commented 1 year ago

yes exactly that πŸš€

Gustutu commented 9 months ago

I am reopening this because i have troubles using sveltekit with orval. When following this tutorial : https://tanstack.com/query/v4/docs/svelte/ssr#using-prefetchquery . I have error specialy Error: Function called outside component initialization .

melloware commented 9 months ago

Prefetch queries were added in Orval 6.20.0 by @georgiev-anton

Gustutu commented 9 months ago

Nice, it works! Thank you for the amazing work πŸ™. It works well, but if I am not mistaken, the integration with SvelteKit is not perfect in my case. SvelteKit want you to use its own fetch function. To achieve this, I need to be able to pass the SvelteKit fetch function down to my custom fetch function. I believe that adding a parameter to the functions generated by Orval to pass the sveltekit fetch function would do the trick. In my case, it results in an unnecessary call from the browser to my backend once the page is loaded.

As you can see, the fetch function used is the one passed as an argument to the load function. This is how fetch request should be made with sveltekit :).

export async function load({ parent, fetch }) {
  const { queryClient } = await parent()

  // You need to use the SvelteKit fetch function here
  await queryClient.prefetchQuery({
    queryKey: ['posts'],
    queryFn: async () => (await fetch('/api/posts')).json()
  })
}

I hope i am not saying nosens. Thanks again for orval :wink:

melloware commented 9 months ago

feel free to provide a PR

Gustutu commented 9 months ago

I will check if there is a clean way to do it without modifying Orval first :) .

georgiev-anton commented 9 months ago

Nice, it works! Thank you for the amazing work πŸ™. It works well, but if I am not mistaken, the integration with SvelteKit is not perfect in my case. SvelteKit want you to use its own fetch function. To achieve this, I need to be able to pass the SvelteKit fetch function down to my custom fetch function. I believe that adding a parameter to the functions generated by Orval to pass the sveltekit fetch function would do the trick. In my case, it results in an unnecessary call from the browser to my backend once the page is loaded.

As you can see, the fetch function used is the one passed as an argument to the load function. This is how fetch request should be made with sveltekit :).

export async function load({ parent, fetch }) {
  const { queryClient } = await parent()

  // You need to use the SvelteKit fetch function here
  await queryClient.prefetchQuery({
    queryKey: ['posts'],
    queryFn: async () => (await fetch('/api/posts')).json()
  })
}

I hope i am not saying nosens. Thanks again for orval πŸ˜‰

maybe it will be useful for you? I override the config so as not to trigger a request when loading the page

module.exports = {
  finsber: {
    output: {
      mode: "tags-split",
      target: "../src/api/v2/reactQuery/reactQueryApi.ts",
      schemas: "../src/api/v2/reactQuery/models",
      client: "react-query",
      override: {
        header: (info) => `// @ts-nocheck
/* tslint:disable */
/* eslint-disable */
/*
    * Generated by orval 🍺
    * Do not edit manually.
    * ${info.title}
    * ${info.description}
    * OpenAPI spec version: ${info.version}
*/
`,
        mutator: {
          path: "../src/api/v2/customAxiosInstance.ts",
          name: "customAxiosInstance",
        },
        query: {
          usePrefetch: true,
          useQuery: true,
          useInfinite: true,
          useInfiniteQueryParam: "page",
          options: {
            staleTime: 10000,
            getNextPageParam: (data) => {
              if (data?.lastPage - (data?.currentPage + 1) < 0) {
                return undefined;
              }
              return data.currentPage + 1;
            },
            keepPreviousData: true,
            refetchOnWindowFocus: false,
            refetchOnMount: false,
            retry: false,
          },
        },
      },
    },
    input: {
      target: "./finsber.yaml",
    },
  },
};

this

query: {
          usePrefetch: true,
          useQuery: true,
          useInfinite: true,
          useInfiniteQueryParam: "page",
          options: {
            staleTime: 10000,
            getNextPageParam: (data) => {
              if (data?.lastPage - (data?.currentPage + 1) < 0) {
                return undefined;
              }
              return data.currentPage + 1;
            },
            keepPreviousData: true,
            refetchOnWindowFocus: false,
            refetchOnMount: false,
            retry: false,
          },
        }
georgiev-anton commented 9 months ago

@Gustutu if this doesn't help you, please make a demo and I'll try to fix it

Gustutu commented 9 months ago

No success in my trials. I will make a demo. I am not sure but i feel that not using the fetch function given in the load function block sveltekit from doing the last bullet point of "Making fetch requests" in this page : sveltekit

Gustutu commented 9 months ago

@georgiev-anton I made a simple demo project with sveltekit and orval if you want to take a look :) .

https://github.com/Gustutu/demo-orval-sveltekit-ssr

Gustutu commented 9 months ago

Seems like it is a known limitation of sveltekit that may be solved someday : :https://github.com/sveltejs/kit/discussions/9033#discussioncomment-7785105

Current solution seems to be passing fetch as argument.