[RFC] Change how queries/mutations access ctx and how middleware is typed
#1052
-
|
Currently queries/mutations access import { SessionContext } from "blitz";
export default async function getUser(
{ where }: GetUserInput,
ctx: { session?: SessionContext } = {}
) {
ctx.session!.authorize();
const user = await db.user.findOne({ where });
return user;
}An you can "chain" resolvers together like this (pass ctx as second arg). import createUser from "./createUser";
export default async function createUsers(
{ users },
ctx: { session?: SessionContext } = {}
) {
for (const user of users) {
await createUser(user, ctx);
}
}There are a few problems with this that necessitates a change.
Requirements
New ProposalsI've come up with two alternate proposals that both significantly improve over the existing approach. If you can think of something better than these, please share it! 1. HOF MethodWe can add a higher order function (HOF) that will add the types for you. The resulting function type is overloaded so that you can call the resolver without import { resolver } from "blitz";
export default resolver(async function getUser({ where }: GetUserInput, ctx) {
ctx.session.authorize();
const user = await db.user.findOne({ where });
return user;
});And you would chain resolvers like this: import { resolver } from "blitz";
import createUser from "./createUser";
export default resolver(async function createUsers({ users }, ctx) {
for (const user of users) {
await createUser(user, ctx);
}
}2.
|
Beta Was this translation helpful? Give feedback.
Replies: 9 comments 21 replies
-
|
One advantage of option 1 is that it allows for the possability to provide metadata as another argument to formulate an SWR cache key or dependency graph which could possibly abstract away useQuery leading to a simpler out of the box frontend API with managed SWR. |
Beta Was this translation helpful? Give feedback.
-
|
In regards to the second options would this technically work? |
Beta Was this translation helpful? Give feedback.
-
|
I think option 1 could break automatic imports from IDEs. |
Beta Was this translation helpful? Give feedback.
-
|
I think a lot of people try to avoid using |
Beta Was this translation helpful? Give feedback.
-
3.
|
Beta Was this translation helpful? Give feedback.
-
|
How do we then test resolvers that use getSession()? I assume we would create an object with a session property and pass it to |
Beta Was this translation helpful? Give feedback.
-
|
In my opinion, all of these proposals add a lot of complexity/magic to the "backend" part. I am very pleased with the look the resolvers have right now, even if they could be more strongly typed: // app/mutations/updateUser.ts
import { Context } from "blitz"
import { User } from "db"
import { UpdateUserInputType } from "../validations"
export default async function updateUser(input: UpdateUserInputType, ctx: Context): Promise<User> => {
ctx.session.authorize()
// ...
}I like to have my types at the right of the // app/mutations/updateUser.ts
import { Mutation } from "blitz"
import { User } from "db"
import { UpdateUserInputType } from "../validations"
const updateUser: Mutation<UpdateUserInputType, User> = (input, ctx) => {
ctx.session.authorize()
// ...
}I think we should do everything we can to preserve this simplicity and strong typing. My proposal:
|
Beta Was this translation helpful? Give feedback.
-
|
Question from Slack:
ctx is always passed by the blitz server internals, regardless of what you do on the frontend. So the core issue is a type mismatch when calling the resolver function directly. Because on the backend ctx is there, but on the frontend you can't pass ctx. So Does that help? |
Beta Was this translation helpful? Give feedback.
-
|
Not sure if this is a good idea, but graphql code generator is generating a hook for each mutation and query to be used directly, so you only need to import one thing and you easily get all the types: https://graphql-code-generator.com/docs/plugins/typescript-react-apollo#usage-example (at the bottom) Maybe a similar thing could be done for blitzjs |
Beta Was this translation helpful? Give feedback.
In my opinion, all of these proposals add a lot of complexity/magic to the "backend" part. I am very pleased with the look the resolvers have right now, even if they could be more strongly typed:
I like to have my types at the right of the
=but we could also provide aQueryandMutationtypes for those who prefer them at the left: