Introducing the new Vue Query client

slickstef11

Stefan 🚀

Posted on May 12, 2023

Introducing the new Vue Query client

VUE FTW

After React and Solid, we now have official Vue support! 🎉.

This new client is built on top of Vue Query, and brings all the good stuff from WunderGraph to the Vue ecosystem. Query, mutate and subscribe to your WunderGraph API fully typesafe in Vue.

The integration has been built by one of our community members, Hebilicious. Thanks Emmanuel, you rock!

Quick start

npx create-wundergraph-app my-project --example nuxt
Enter fullscreen mode Exit fullscreen mode

Installation

Let's have a quick look at how to set it up in a Nuxt project and how to use it. (this assumes you already have Nuxt and WunderGraph installed).

Install the Vue Query client:

npm install @wundergraph/vue-query @tanstack/vue-query
Enter fullscreen mode Exit fullscreen mode

Configuration

Before you can use the hooks, you need to modify your code generation to include the base typescript client.

 {% filename="wundergraph.config.ts" %}
// wundergraph.config.ts
configureWunderGraphApplication({
  // ... omitted for brevity
  codeGenerators: [
    {
      templates: [templates.typescript.client],
      // the location where you want to generate the client
      path: './components/generated',
    },
  ],
})
Enter fullscreen mode Exit fullscreen mode

Now we need to configure the Vue Query client. We'll create a plugin for this.

 {% filename="plugins/vue-query.ts" %}
import type {
  DehydratedState,
  VueQueryPluginOptions,
} from '@tanstack/vue-query'
import {
  VueQueryPlugin,
  QueryClient,
  hydrate,
  dehydrate,
} from '@tanstack/vue-query'
import { useState } from '#app'

import { createHooks } from '@wundergraph/vue-query'
import { createClient, Operations } from '../components/generated/client'

export default defineNuxtPlugin((nuxt) => {
  const vueQueryState = useState<DehydratedState | null>('vue-query')

  const queryClient = new QueryClient({
    defaultOptions: { queries: { staleTime: 5000 } },
  })
  const options: VueQueryPluginOptions = { queryClient }

  nuxt.vueApp.use(VueQueryPlugin, options)

  if (process.server) {
    nuxt.hooks.hook('app:rendered', () => {
      vueQueryState.value = dehydrate(queryClient)
    })
  }

  if (process.client) {
    nuxt.hooks.hook('app:created', () => {
      hydrate(queryClient, vueQueryState.value)
    })
  }

  const client = createClient() // Typesafe WunderGraph client
  const wgraph = createHooks<Operations>(client)
  return {
    provide: {
      wgraph,
    },
  }
})
Enter fullscreen mode Exit fullscreen mode

Usage

Queries

{% filename="pages/index.vue" %}
<script setup lang="ts">
  const { $wgraph } = useNuxtApp();
  const { data, suspense } = $wgraph.useQuery({
    operationName: 'Dragons',
    input: {
      limit: 1,
    },
  });
  await suspense();
</script>
Enter fullscreen mode Exit fullscreen mode

Turn queries into live queries, live queries are refetched on a interval on the WunderGraph server.

{% filename="pages/index.vue" %}
<script setup lang="ts">
  const { $wgraph } = useNuxtApp();
  const { data, suspense } = $wgraph.useQuery({
    operationName: 'Dragons',
    input: {
      limit: 1,
    },
    liveQuery: true
  });
  await suspense();
</script>
Enter fullscreen mode Exit fullscreen mode

Subscriptions

Build realtime apps with subscriptions.

{% filename="pages/index.vue" %}
<script setup lang="ts">
  const { $wgraph } = useNuxtApp();
  const { data, suspense } = $wgraph.useSubscription({
    operationName: 'Countdown',
    input: {
      from: 1,
    },
  });
  await suspense();
</script>
Enter fullscreen mode Exit fullscreen mode

Mutations

 {% filename="pages/index.vue" %}
<script lang="ts" setup>
const {
    $wgraph: { useMutation },
} = useNuxtApp();

const id = ref('1');
const name = ref('Jens');
const bio = ref('Founder of WunderGraph');

const { data, mutate } = useMutation({
    operationName: 'users/update',
});
</script>
Enter fullscreen mode Exit fullscreen mode

Invalidating queries

Let's say we have a query that fetches the current user's profile in one component and we have a form that updates the profile. We can add an onSuccess handler to the mutation that calls queryClient.invalidateQueries on the GetProfile query and trigger a refetch and update the internal React Query cache.

 {% filename="pages/index.vue" %}
<script lang="ts" setup>
import { useQueryClient, useQuery, useMutation } from "@tanstack/vue-query";

// Access QueryClient instance
const queryClient = useQueryClient();

const {
    $wgraph: { useMutation, queryKey },
} = useNuxtApp();

const id = ref('1');
const name = ref('Jens');
const bio = ref('Founder of WunderGraph');

const { data, mutate } = useMutation({
    operationName: 'users/update',
  onSuccess: () => {
    // Invalidate and refetch
    queryClient.invalidateQueries(queryKey({operationName: 'GetProfile'}));
  },
});
</script>
Enter fullscreen mode Exit fullscreen mode

Check out the reference and example app below to learn more about the new Vue Query integration.

Resources

Summary

We're very excited to see the community building integrations for WunderGraph. If you have ideas for other integrations, let us know in the comments below or join us on our Discord server.

💖 💪 🙅 🚩
slickstef11
Stefan 🚀

Posted on May 12, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related