下面是我刚刚在Vercel上部署的website。我正在使用Prisma和Next.js构建一个Web应用程序,我遇到了一个问题,内容无法实时更新,直到我手动重新部署应用程序。情况是这样的:
- 我在Next.js应用程序中有一个API端点,可以从Prisma数据库中获取数据。
- 当我通过应用程序在数据库中创建或更新数据时,更改会立即反映在开发环境中,但直到我重新部署应用程序后,这些更改才会反映在生产环境中。
这是我在前端获取数据的方式:
第一个月
这是发布内容的API端点:
// Addposts to prisma backend
import { NextResponse, NextRequest } from 'next/server';
import prisma from '../../../prisma/client';
// Function
export async function POST(request:NextRequest) {
const data = await request.json();
const title = data.title;
const user = await prisma.user.findUnique({
where: {
email : data.email
}
})
if (!user){
// return error
return NextResponse.json({error: "User not found"}, {status: 404})
}
if (!title){
// throw error
return NextResponse.json({error: "Title is required"}, {status: 400})
}
if (title.length > 300){
return NextResponse.json({error:"Title should not be more than 300 characters"}, {status:400});
}
const userId = user?.id;
const post = await prisma.post.create({
data: {
title,
userId
}
})
try{
return NextResponse.json({post},{status:200})
}catch(error){
return NextResponse.json({error}, {status:500})
}
}
字符串
获取所有帖子的API端点:
import { NextRequest, NextResponse } from 'next/server'
import prisma from '../../../prisma/client'
import { NextApiResponse } from 'next';
export async function GET(request:NextRequest){
const posts = await prisma.Post.findMany({
include: {
user: true
},
orderBy:{
createdAt: 'desc'
}
})
try{
// return all the posts
return NextResponse.json({posts},{status:200})
}catch(error){
return NextResponse.json(error, {status:500});
}
}
型
如何确保内容更新立即反映在生产环境中,而无需手动重新部署?
下面是GitHub存储库的link。
更新
- 我能够发出POST请求并对数据库进行更改,我认为问题在于GET请求,因为即使在刷新页面时,数据也似乎是静态的。*
以下是我在Vercel上的运行时日志:
的数据
3条答案
按热度按时间km0tfn4u1#
好了,经过几天的调试,这是为我工作的:
我将GET和POST函数移到了一个route.ts文件中。
之前:
这是我如何完成GET请求的:
axios.get(url/api/getPosts)
和我的POST请求axios.post(url/api/addPosts)
之后:
这是我如何完成GET请求的:
axios.get(url/api/Posts)
和我的POST请求axios.post(url/api/Posts)
shyt4zoc2#
const { data: posts, error } = useSWR(
/API/getPost, fetcher, {refreshInterval:1000});
这意味着你正在使用SWR,这是用于数据获取的React钩子。
我看到SWR有一个mutation function,这将是有趣的:您可以使用SWR的
mutate()
函数来更新缓存并重新获取数据。在您的存储库
Sadeedpv/tweet-it
中,我看到您有一个app/components/InputField.tsx
,它处理提交功能。它向/api/addPosts
端点发出POST请求您可以修改
handleSubmit
函数,以便在创建post后也重新验证SWR缓存,如下所示:字符串
通过调用
mutate('/api/getPosts')
,您将告诉SWR重新验证/api/getPosts
端点上的数据。这应该可以确保在成功创建新帖子后,立即在应用中更新帖子列表。InputField.tsx
组件的其余部分可以保持不变。当您在
InputField
组件中调用mutate('/api/getPosts')
时,您使用的是“mounted SWR hook using the same key”(/api/getPosts
),如SWR文档所示。这意味该高速缓存将被更新,并将触发重新验证,这就是您在这里可能需要的。这可能比在
fetch
请求中包含一个“无存储”缓存选项要轻,比如:型
如果你发现你的应用由于Next.js的默认缓存行为而提供陈旧的数据,你可以使用
no-store
选项绕过该高速缓存,并始终从服务器获取新的数据。如果数据保持静态,请尝试禁用服务器端缓存,以进行测试:对从Prisma数据库获取数据的特定Next.js API路由执行此操作。您可以通过在服务器端代码中设置适当的
Cache-Control
头来实现这一点。型
s-maxage=1, stale-while-revalidate
cache-control指令告诉服务器将响应缓存1秒,如果该高速缓存过时,则在后台重新验证缓存的同时处理过时的数据。参见Rishi Raj Jain中的“Next.js | SWR (Stale While Revalidate) — Introduction”。
此外,还包括:
我想知道这是否与我设置PrismaClient的方式有关
根据Vercel管理无服务器函数示例的方式,可能是Prisma Client的陈旧示例导致了问题。您可以尝试确保为每个请求创建一个新的Prisma Client示例:
型
然后在您的API路由中,您将执行以下操作:
型
使用Prisma客户端后,请务必断开连接,以避免任何潜在的连接问题:
型
我尝试了更新的解决方案,但不幸的是,它没有解决我的问题。
然后你需要更多的调试信息:
在API端点中添加
console.log
语句以跟踪请求和响应。这可以帮助您了解API请求是否正常工作以及响应数据是否符合预期。型
注意:无服务器函数的控制台日志(如Vercel的API路由)不会出现在浏览器的控制台中。您需要检查Vercel的功能日志以了解这些信息。您可以通过your Vercel dashboard访问这些日志。
如果您还没有,请尝试使用像Postman这样的工具在本地测试您的API路由。这有助于确定问题是出在代码上还是出在部署环境上。
并确认您的Prisma客户端可以正确连接到您的数据库。您可以在API路由启动时添加一个检查,以查看它们是否可以连接到数据库。
型
您还可以将onSuccess和onError回调添加到SWR钩子中,以帮助调试潜在的问题。
型
根据您收集的信息,可能是API端点、与数据库的连接或客户端的数据处理出现问题。
要添加到OP's solution,请执行以下操作:
SWR和Next.js都有自己的缓存机制:
每个端点的Next.js无服务器函数可能已经创建了Prisma客户端的新示例。因此,每个函数中的Prisma客户端可能不知道Prisma客户端在另一个函数中所做的更改。
将
GET
和POST
操作合并到一个函数中,可以确保它们共享Prisma客户端的同一个示例,因此两者具有相同的数据库视图。之前,您有两个独立的端点,一个用于获取帖子(
/api/getPosts
),另一个用于添加帖子(/api/addPosts
)。在更改之后,您将它们整合到一个端点(
/api/Posts
)中,该端点同时处理GET
和POST
请求。这实际上是RESTful API设计中的一种常见模式,其中单个URL或端点Map到资源,HTTP方法的类型(
GET
,POST
,PUT
,DELETE
等)确定要对该资源采取的操作。举例来说:
GET /api/Posts
:获取文章列表POST /api/Posts
:创建新帖子这种方法的好处是它简化了API结构,并且更容易理解每个端点基于标准HTTP方法所做的事情。
jk9hmnmh3#
这是因为GET处理程序没有使用request,并且在生产环境中它是静态生成的(https://nextjs.org/docs/app/building-your-application/routing/router-handlers)。无论你是否使用SWR-你的API处理程序是纯html,它总是保持不变,返回在构建时预取的相同数据。
字符串
在GET API处理程序中将解决这个问题。