两种接口调用方式
1.直接graphQL查询,服务端(大部分增对数据库的curd操作,serverless)
第一种:usequery
useKnowledgeBaseListQuery
import { useKnowledgeBaseListQuery } from '@/graphql/generated/types'
const { data, refetch ,loading,error } = useKnowledgeBaseListQuery({
variables: {
where: {
_or: [
{ is_publish: { _eq: true } },
{ creator_id: { _eq: session.data?.user?.id } },
],
},
limit: 5,
},
})
const debouncedRefetch = useCallback(
debounce((term: string) => {
refetch({
where: {
_and: [
{
_or: [
{ is_publish: { _eq: true } },
{ creator_id: { _eq: session.data?.user?.id } },
],
},
term ? { name: { _ilike: `%${term}%` } } : {},
],
},
limit: 5,
})
}, 300),
[refetch, session.data?.user?.id],
)
const handleSearchChange = (value: string) => {
setSearchTerm(value)
debouncedRefetch(value)
}
返回data和refetch 可以重新refetch 来更新data
特点:
- 组件渲染时立即执行查询
适用场景:
- 页面初始加载就需要数据的情况
- 列表页面的首次加载
- 详情页面需要立即显示的数据
- 当数据是渲染组件的必需条件时
第二种 uselazyquery
封装fetchdata函数来获取数据
const [knowledgeBaseListLazyQuery,{data,loading,error}] = useKnowledgeBaseListLazyQuery()
const fetchData = useCallback(
async (page: number, search: string) => {
const currentOffset = (page - 1) * ITEMS_PER_PAGE
try {
const res = await knowledgeBaseListLazyQuery({
variables: {
where: {
creator_id: { _eq: userId },
...(search
? {
_or: [
{ name: { _ilike: `%${search}%` } },
// Add more fields to search as needed
],
}
: {}),
},
order_by: { updated_at: Order_By.Desc },
offset: currentOffset,
limit: ITEMS_PER_PAGE,
},
})
if (res.data) {
setLibraryList((prev) => {
const newLibraries = res.data?.knowledge_base || []
const existingIds = new Set(newLibraries.map((l) => l.id))
const filteredPrev = prev.filter((l) => !existingIds.has(l.id))
return [...filteredPrev, ...newLibraries]
})
const totalCount = res.data?.knowledge_base_aggregate?.aggregate?.count || 0
setHasMore(ITEMS_PER_PAGE * (page - 1) <= totalCount)
console.log('totalCount', totalCount)
console.log('userId', userId)
}
} catch (error) {
console.error('Error fetching data', error)
toast.error(t('Error fetching workflow data'))
}
},
[page, search, userId],
)
特点:
- 返回一个触发函数,只有在调用这个函数时才会执行查询
适用场景:
- 按钮点击后才需要加载数据
- 条件查询,用户输入搜索条件后再查询
- 分页加载更多数据
- 需要用户交互才触发的数据加载
第三种 服务端写法
直接在服务端组件fetchData并向下传递
import { auth } from '@/auth'
import LibraryList from '@/components/Library/LibraryList'
import {
KnowledgeBaseListDocument,
KnowledgeBaseListQuery,
KnowledgeBaseListQueryVariables,
Order_By,
} from '@/graphql/generated/types'
import { fetchData } from '@/lib/apolloRequest'
const ITEMS_PER_PAGE = 15
const fetchLibraryData = async (page: number) => {
const session = await auth()
if (!session?.user) return null
const variables: KnowledgeBaseListQueryVariables = {
order_by: { updated_at: Order_By.DescNullsLast },
where: { creator_id: { _eq: session.user.id } },
limit: ITEMS_PER_PAGE,
offset: (page - 1) * ITEMS_PER_PAGE,
}
return await fetchData<KnowledgeBaseListQuery, KnowledgeBaseListQueryVariables>(
KnowledgeBaseListDocument,
variables,
)
}
export default async function LibraryPage({
searchParams,
}: {
searchParams: { [key: string]: string | string[] | undefined }
}) {
const t = await getTranslations()
const page = Number(searchParams.page) || 1
const libraryListData = await fetchLibraryData(page)
async function refreshLibraryData() {
'use server'
const data = await fetchLibraryData(page)
return data?.knowledge_base || []
}
return (
<LibraryList
initialLibraryList={libraryListData?.knowledge_base || []}
refreshAction={refreshLibraryData}
/>
)
}
2.使用nextjs的api方式调后端接口,需要服务端参与的rest接口
参考例子:api/auth/send_verify_email/route.ts
import '@/lib/apiClient'
import { AuthService, ResetPasswordRequestSchema } from '@/restful/generated'
import { NextRequest, NextResponse } from 'next/server'
export async function POST(req: NextRequest) {
try {
const body: ResetPasswordRequestSchema = await req.json()
const response = await AuthService.resetPasswordV1AuthResetPasswordPost({
requestBody: body,
})
return NextResponse.json(response)
} catch (error: any) {
console.error('Error resetting password:', error)
return NextResponse.json({ message: error.body.detail }, { status: error.status })
}
}
封装后端提供的接口 AuthService.sendVerifyEmailV1AuthSendVerifyEmailPost