项目接口调用总结

105 阅读1分钟

 

两种接口调用方式

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