We're excited to announce that we now have official Solid.js support! 🎉. This new client is built on top of TanStack Solid Query, and brings all the good stuff from WunderGraph to the Solid.js ecosystem. Query, mutate and subscribe to your WunderGraph API fully typesafe in Solid.js.
The release is still in beta and we're looking for feedback on the API and how it works with Solid.js. If you have any feedback, please let us know by opening an issue on Github or talk to us directly on Discord.
Let's go through quickly how to set it up and how it works.
Installation
Install the Solid Query client:
npm install @wundergraph/solid-query @tanstack/solid-query
Configuration
Before you can use the hooks, you need to modify your code generation to include the base typescript client.
// wundergraph.config.ts
configureWunderGraphApplication({
// ... omitted for brevity
codeGenerators: [
{
templates: [templates.typescript.client],
// the location where you want to generate the client
path: '../src/generated',
},
],
})
Now you can configure the hooks. Create a new file, for example src/lib/wundergraph.ts
and add the following code:
import { createHooks } from '@wundergraph/solid-query'
import { createClient, Operations } from '../generated/client'
const client = createClient() // Typesafe WunderGraph client
export const {
createQuery,
createMutation,
createSubscription,
createFileUpload,
useUser,
useAuth,
queryKey,
} = createHooks<Operations>(client)
Queries
const weather = createQuery({
operationName: 'Weather',
input: {
forCity: 'Berlin',
},
})
weather.data
Turn queries into live queries, live queries are refetched on a interval on the WunderGraph server.
const liveWeather = createQuery({
operationName: 'Weather',
input: {
forCity: 'Berlin',
},
liveQuery: true,
})
Subscriptions
Build realtime apps with subscriptions.
const subscription = createSubscription({
operationName: 'Countdown',
input: {
from: 100,
},
})
Mutations
const mutation = createMutation({
operationName: 'SetName',
})
mutation.mutate({ name: 'Eelco' })
// Async mutate
const result = await mutation.mutateAsync({ name: 'Eelco' })
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.
const Profile = () => {
const query = createQuery({
operationName: 'GetProfile',
})
return <div>{query.data?.getProfile.name}</div>
}
const FormComponent = () => {
const queryClient = useQueryClient();
const mutation = createMutation({
operationName: 'UpdateProfile',
onSuccess() {
// invalidate the query
queryClient.invalidateQueries(queryKey({ operationName: 'GetProfile' }));
},
})
const onSubmit = (event) => {
e.preventDefault();
const data = new FormData(event.target);
mutation.mutate(data)
}
return <form onSubmit={onSubmit}><input name="name" /><button type="submit">Save></button></form>
}
Now we could even make this fully optimistic by updating the GetProfile
cache instead and then refetching it, it would look something like this:
const FormComponent = () => {
const queryClient = useQueryClient()
const mutation = createMutation({
operationName: 'UpdateProfile',
onMutate: async (data) => {
const key = queryKey({ operationName: 'GetProfile' })
// Cancel any outgoing refetches
// (so they don't overwrite our optimistic update)
await queryClient.cancelQueries(key)
// Snapshot the previous value
const previousProfile = queryClient.getQueryData<Profile>(key)
// Optimistically update to the new value
if (previousProfile) {
queryClient.setQueryData<Profile>(key, {
...previousProfile,
...data,
})
}
return { previousProfile }
},
// If the mutation fails,
// use the context returned from onMutate to roll back
onError: (err, variables, context) => {
if (context?.previousProfile) {
queryClient.setQueryData<Profile>(
queryKey({ operationName: 'GetProfile' }),
context.previousProfile
)
}
},
// Always refetch after error or success:
onSettled: () => {
queryClient.invalidateQueries(queryKey({ operationName: 'GetProfile' }))
},
})
const onSubmit = (event) => {
e.preventDefault()
const data = new FormData(event.target)
mutation.mutate(data)
}
return (
<form onSubmit={onSubmit}>
<input name="name" />
<button type="submit">Save</button>
</form>
)
}
Check out the reference and example app below to learn more about the new Solid Query integration.
Resources
Summary
You can now leverage the power of WunderGraph with Solid.js, we are excited to see what you'll build with it.
Thanks go out to Tanstack for making this awesome async state management library. We will be releasing Svelte and Vue integrations soon, stay tuned!
We would love to know more about your experience with Solid.js. Do you use Vite, or Solid Start? What do you like about it?
Share it in the comments below or come join us on our Discord server.
Top comments (0)