-
-
Notifications
You must be signed in to change notification settings - Fork 798
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
Define Query & Mutation Usage (useQuery, cache invalidation, etc.) #89
Comments
Does that mean there will be no option to cache queries on the server-side? We need data caching and SSR Suspense for our web app. React Suspense with react-cache is also an option in the future - https://hackernoon.com/magic-of-react-suspense-with-concurrent-react-and-react-lazy-api-e32dc5f30ed1 |
@cr101 good question. What type of caching do you need on the server? And do you need this for serverful or serverless deployment? Blitz will definitely support SSR suspense — as soon as Next.js does, which I expect to be at or soon after the production release. |
I would imagine that might be a good candidate for an optional middleware? |
On the surface |
As far as this API is concerned this client-side cache invalidation stuff is getting complex. Could we possibly be straying away from the core premise of blitz that you should never need to worry about data fetching? I am wondering if we could merge queries into a resource if we would then get more automatic mileage in terms of cache invalidation after mutations as you could configure this is a resource and it's queries, mutations and cache could be linked? Thoughts? Perhaps the above API could be for advanced usage? const productResource = createResource({
get: getProduct,
update: updateProduct,
create: createProduct,
delete: deleteProduct
});
export default function(props: {query: {id: number}}) {
const [product] = useResource(productResource.get({where: {id: props.query.id}}))
return (
<Formik
initialValues={product}
onSubmit={async values => {
try {
const product = await productResource.update(values)
} catch (error) {
alert('Error saving product')
}
}}>
{/* ... */}
</Formik>
)
} I know this has echoes of the serverside rails controllers we had before. |
Invalidating cache on route transitions is quite simple, yeah? And instead of requiring an opt-in, we could automatically invalidate cache on route transitions and then have an option to opt out.
Unless we enforce 100% SSR, then there's no way to get around client side cache. So the best we can do is make the common case extremely simple. I think a route transition will be the most common case. |
SSR doesn't help with client side cache unless you mean full server rendered pages on every interaction which is not an option. This could be a leaky abstraction if application developers don't change page routes after mutations. Think edit in place fields. Spreadsheets. Drag and drop interfaces. Not every app has a save button. The common case is crud interactions not route transitions. I think we need to link interactions to inform the way the cache works by default. Could be configuration doesn't matter how. Could even be convention inferred by cache key? ie. the path of the query method or the name of the interaction. |
I'll think more about the cache stuff and report back later. I realized something I overlooked: applying middleware in Here's what I'm thinking. Thoughts? import {ssrQuery} from 'blitz'
import getProduct from '/app/products/queries/getProduct'
export const getServerSideProps = async ({params, req, res}) => {
const product = await ssrQuery(getProduct, {where: {id: params.id}}, {req, res}))
return {props: {product}}
}
export default function({product}) {
return <div>{product.name}</div>
} Alternately, we could use a babel transform to add the req and res objects to the ssrQuery call so the user doesn't have to. But I don't really think that's a good idea. |
as blitz does not support graphql it would become out of hand to define and maintaining queries and their types in large project. |
The |
Will it be possible to query the database using raw queries via prisma.raw()? |
@cr101, yes you bet! You have full access to prisma. The only thing we are planning to do for now is wrap the prisma CLI like |
Closing as complete! I've added the documentation form here to the new docs website that will go live within a day or so. I also opened #586 to discuss automatic cache invalidation. |
We need to define exactly how queries and mutations are used in Blitz app code.
Requirements
getStaticProps
) should directly use the query/mutation. It should not make an RPC call to another lambdaQueries
In a React Component
Blitz provides a
useQuery
hook. The first argument is a query function. The second argument is the input to the query function.react-query
under the hood for implementing this hook.On the Server
In server-side code, a query function can be called directly without
useQuery
Cache Key
["/api/products/queries/getProduct", {where: {id: props.query.id}]
React Suspense & Concurrent Mode
Blitz apps have concurrent mode enabled by default, so suspense for data fetching is also our default.
SSR Suspense
Our current plan is to not support SSR for
useQuery
. We're hoping the official new concurrent mode SSR renderer is out within a few months.useQuery
Dependent Queries
The second query will not execute until the second function argument can be called without throwing.
Prefetching (not implemented: blitz-js/legacy-framework#821)
Both of the following will cache the
getProduct
query.Pagination
Use the
usePaginatedQuery
hookInfinite Loading (not implemented: blitz-js/legacy-framework#819)
SSR
Queries can be used for SSR with the
ssrQuery
function.ssrQuery
will run the appropriate middleware.Window-Focus Refetching
If a user leaves your application and returns to stale data, you usually want to trigger an update in the background to update any stale queries. Blitz useQuery will do this automatically for you, but there will be an option to disable it.
Optimistic Updates
I think optimistic updates should very rarely be used. The UX for end-users is very tricky to get right with optimistic updates.
Therefore, I think optimistic updates should not have first-class support in Blitz. If users need this, they can use directly use react-query or some other method.
Advanced Features & Config
We accept any react-query config item as the third argument to
useQuery
.These include
refetchInterval
,initialData
,retry
,retryDelay
,cacheTime
, etc.Mutations
Mutations are called directly. There is no
useMutation
hook like react-query has.Cache Invalidation (not implemented)
refetch
mutate
On Route Transition
Router.push
andRouter.replace
accepts arefetchQueries
option, that when true, will cause all queries on the destination page to be invalidated.refetch
useQuery
returns arefetch
function you can use to trigger a query reloadmutate
useQuery
returns amutate
function you can use to manually update the cachemutate
will automatically trigger a refetch for the initial query to ensure it has the correct datamutate
will be fully typed for Typescript usageRelated Blitz Issues
The text was updated successfully, but these errors were encountered: