zid
zid11mo ago

Using convex server-side (nextJS api routes)

Having some trouble getting convex to work inside NextJS api routes. This is inside /api/fn.js The mutation fn is defined but the fn is not executing..
import { mutation } from "@/convex/_generated/server";

// ...
await mutation(async ({ db }, { arg1, arg2 }) => {

await db.patch(userId, {
// ...
});

});
import { mutation } from "@/convex/_generated/server";

// ...
await mutation(async ({ db }, { arg1, arg2 }) => {

await db.patch(userId, {
// ...
});

});
6 Replies
Michal Srb
Michal Srb11mo ago
What does your Next.js code look like?
zid
zidOP11mo ago
ehm, its a little verbose given the context (webhook for stripe) The above code sample was from that page but lets see
import Stripe from "stripe";
import getRawBody from "raw-body";
import { mutation } from "@/convex/_generated/server";

const updateSubscriptionStatus = mutation(
async ({ db }, { userId, status, failedPayment }) => {
console.log("updateSubscriptionStatus", { userId, status, failedPayment });

await db.patch(userId, {
active: status,
failedPayment: failedPayment,
});
}
);

switch(eventType) {
case "one":

await updateSubscriptionStatus({
userId: userId,
status: true,
failedPayment: false,
});
break;
case "two:

await mutation(async ({ db }, { arg1, arg2 }) => {
await db.patch(userId, {
active: true,
failedPayment: false,
});
});
}
// ...
import Stripe from "stripe";
import getRawBody from "raw-body";
import { mutation } from "@/convex/_generated/server";

const updateSubscriptionStatus = mutation(
async ({ db }, { userId, status, failedPayment }) => {
console.log("updateSubscriptionStatus", { userId, status, failedPayment });

await db.patch(userId, {
active: status,
failedPayment: failedPayment,
});
}
);

switch(eventType) {
case "one":

await updateSubscriptionStatus({
userId: userId,
status: true,
failedPayment: false,
});
break;
case "two:

await mutation(async ({ db }, { arg1, arg2 }) => {
await db.patch(userId, {
active: true,
failedPayment: false,
});
});
}
// ...
Let me know if theres anything else youd like to see
jamwt
jamwt11mo ago
any reason you're not just using a convex http action for the stripe webhook? (ala https://www.convex.dev/templates/stripe )
Templates
The backend application platform with everything you need to build your product.
ian
ian11mo ago
You can't call define and a mutation in a nextjs api route locally. You have to define and export the mutation from within a file in the convex/ directory, then call it from a Convex client using something like api.mymodule.updateSubscriptionStatus. Does that make sense? And to echo Jamie, you can avoid having the nextjs api route by using http actions in convex, which let you do ctx.runMutation(api.mymodule.updateSubscriptionStatus, args) - which also allows you to make the mutation an internal function so no one can call it from outside of your Convex backend.
JavaScript | Convex Developer Hub
Convex applications can be accessed from Node.js or any JavaScript runtime that
Internal Functions | Convex Developer Hub
Internal functions can only be called by other functions
zid
zidOP11mo ago
@jamwt Ah, thank you! And good question...the biggest reason is that I wasn't thorough enough with documentation; my fault entirely. I forgot there was such a thing as actions! Ive never used it before and I think I had assumed that I knew the api already and quickly scanned through the docs to find something with "server" in it. Looking forward to diving in! Ahh...right...thank you for the kind reminder. Goodness! Thank you, Ian!
jamwt
jamwt11mo ago
@zid cool! while it is possible to call your convex project from vercel functions, it's much easier to just use an http action as a web hook and handle everything on the convex side

Did you find this page helpful?