NextJS(13) API call cache MISS
Hey everyone hoping for some help with an issue that is cause me a mountain of headaches. My app is having webhooks forwarded to my API route from StipeCLI. if a certain event type is forwarded I want to fetch an API route in my Next app. shown below:
(BEEN STUCK FOR A WEEK< PLZ HELP)
below is the /api/clerk/add-credits route I want to fetch
My issue is when the fetch runs i get a console message of :
┌ POST /api/stripe/webhook 200 in 1008m
│
└──── GET http://localhost:3000/api/clerk/add-credits 200 in 930ms (cache: MISS)
switch (event.type) {
case 'checkout.session.completed':
const reqUrl = new URL(req.url);
await fetch(`${reqUrl.origin}/api/clerk/add-credits`, {
method: 'GET',
});
console.log(':white_check_mark: checkout session completed webhook received');
break;
default:
console.log(`Unhandled event type ${event.type}`);
}
switch (event.type) {
case 'checkout.session.completed':
const reqUrl = new URL(req.url);
await fetch(`${reqUrl.origin}/api/clerk/add-credits`, {
method: 'GET',
});
console.log(':white_check_mark: checkout session completed webhook received');
break;
default:
console.log(`Unhandled event type ${event.type}`);
}
import { auth, clerkClient } from '@clerk/nextjs/server';
import { NextRequest, NextResponse } from 'next/server';
export async function GET(req: NextRequest, res: NextResponse) {
res.headers.set('Access-Control-Allow-Origin', '*');
res.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.headers.set(
'Access-Control-Allow-Headers',
'Content-Type, Authorization'
);
res.headers.set('Access-Control-Allow-Credentials', 'true');
const { userId } = auth();
if (typeof userId !== 'string') return;
const user = await clerkClient.users.getUser(userId);
const credits: any = user.publicMetadata.credits;
try {
const updatedUser = await clerkClient.users.updateUserMetadata(userId, {
publicMetadata: {
credits: credits + 100,
},
});
NextResponse.json({ success: true, user: updatedUser });
console.log('added credits');
} catch (err) {
console.error('error deducting credits', err);
}
}
import { auth, clerkClient } from '@clerk/nextjs/server';
import { NextRequest, NextResponse } from 'next/server';
export async function GET(req: NextRequest, res: NextResponse) {
res.headers.set('Access-Control-Allow-Origin', '*');
res.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.headers.set(
'Access-Control-Allow-Headers',
'Content-Type, Authorization'
);
res.headers.set('Access-Control-Allow-Credentials', 'true');
const { userId } = auth();
if (typeof userId !== 'string') return;
const user = await clerkClient.users.getUser(userId);
const credits: any = user.publicMetadata.credits;
try {
const updatedUser = await clerkClient.users.updateUserMetadata(userId, {
publicMetadata: {
credits: credits + 100,
},
});
NextResponse.json({ success: true, user: updatedUser });
console.log('added credits');
} catch (err) {
console.error('error deducting credits', err);
}
}
8 Replies
the second parameter to the GET function is not NextResponse
you set the headers by adding them to the Response object you return from the function
Routing: Route Handlers
Create custom request handlers for a given route using the Web's Request and Response APIs.
i dont quite understand, Am n00b
They changed this in next 13
You need to send headers like this
Line 4:
export async function GET(req: NextRequest, res: NextResponse) {
^
|
This parameter doesn't exist, remove it
Line 4:
export async function GET(req: NextRequest, res: NextResponse) {
^
|
This parameter doesn't exist, remove it
const headers = new Headers({
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
'Access-Control-Allow-Credentials': 'true'
})
return new Response(body, {
headers: headers
})
const headers = new Headers({
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
'Access-Control-Allow-Credentials': 'true'
})
return new Response(body, {
headers: headers
})
like this?
import { auth, clerkClient } from '@clerk/nextjs/server';
import { NextRequest, NextResponse } from 'next/server';
export async function GET(req: NextRequest) {
console.log('✅ Received request to add credits');
const headers = new Headers({
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
'Access-Control-Allow-Credentials': 'true',
});
const { userId } = auth();
console.log('Got userId:', userId);
if (typeof userId !== 'string') return;
const user = await clerkClient.users.getUser(userId);
console.log('Got user:', user);
const credits: any = user.publicMetadata.credits;
try {
const updatedUser = await clerkClient.users.updateUserMetadata(userId, {
publicMetadata: {
credits: credits + 100,
},
});
console.log('added credits');
return NextResponse.json({ success: true, user: updatedUser });
} catch (err) {
console.error('error deducting credits', err);
}
return new Response(req.body, {
headers: headers,
});
}
import { auth, clerkClient } from '@clerk/nextjs/server';
import { NextRequest, NextResponse } from 'next/server';
export async function GET(req: NextRequest) {
console.log('✅ Received request to add credits');
const headers = new Headers({
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
'Access-Control-Allow-Credentials': 'true',
});
const { userId } = auth();
console.log('Got userId:', userId);
if (typeof userId !== 'string') return;
const user = await clerkClient.users.getUser(userId);
console.log('Got user:', user);
const credits: any = user.publicMetadata.credits;
try {
const updatedUser = await clerkClient.users.updateUserMetadata(userId, {
publicMetadata: {
credits: credits + 100,
},
});
console.log('added credits');
return NextResponse.json({ success: true, user: updatedUser });
} catch (err) {
console.error('error deducting credits', err);
}
return new Response(req.body, {
headers: headers,
});
}
still getting same console with these 2 code blocks
import { NextResponse } from 'next/server';
import { buffer } from 'node:stream/consumers';
import { stripe } from '~/lib/stripe';
export async function POST(request: any) {
let event: any;
const rawBody = await buffer(request.body);
try {
event = stripe.webhooks.constructEvent(
rawBody,
request.headers.get('stripe-signature') as string,
process.env.STRIPE_WEBHOOK_SIGNING_SECRET as string
);
} catch (err) {
console.log(err);
return NextResponse.json(
{
message: 'Webhook signature verification failed',
},
{
status: 400,
}
);
}
if (event.type === 'checkout.session.completed') {
const reqUrl = new URL(request.url);
console.log(':white_check_mark: checkout session completed webhook received');
await fetch(`${reqUrl.origin}/api/clerk/add-credits`, {
method: 'GET',
});
console.log(':white_check_mark: credits added');
}
return new Response('ok', {
status: 200,
});
}
import { NextResponse } from 'next/server';
import { buffer } from 'node:stream/consumers';
import { stripe } from '~/lib/stripe';
export async function POST(request: any) {
let event: any;
const rawBody = await buffer(request.body);
try {
event = stripe.webhooks.constructEvent(
rawBody,
request.headers.get('stripe-signature') as string,
process.env.STRIPE_WEBHOOK_SIGNING_SECRET as string
);
} catch (err) {
console.log(err);
return NextResponse.json(
{
message: 'Webhook signature verification failed',
},
{
status: 400,
}
);
}
if (event.type === 'checkout.session.completed') {
const reqUrl = new URL(request.url);
console.log(':white_check_mark: checkout session completed webhook received');
await fetch(`${reqUrl.origin}/api/clerk/add-credits`, {
method: 'GET',
});
console.log(':white_check_mark: credits added');
}
return new Response('ok', {
status: 200,
});
}
🙏🙏🙏
Ty