如何基于 GraphQL API 的 slug 使用 Next.js 进行动态路由?
Posted
技术标签:
【中文标题】如何基于 GraphQL API 的 slug 使用 Next.js 进行动态路由?【英文标题】:How do I do dynamic routing with Next.js based on slug from GraphQL API? 【发布时间】:2021-04-25 09:08:15 【问题描述】:我很难理解基于变量的动态路由。我可以使用 Next.js 获取具有动态路由的单个页面的集合中的项目列表,但不能获取单个项目及其字段。
背景
我有一个带有 GraphQL API 的 KeystoneJS 无头 CMS。我正在尝试创建一个包含帖子列表和单个帖子页面的简单博客。我已经能够查询并返回一个帖子列表,但我需要根据 slug 字段获取一个单独的帖子,以便可以通过/posts/[slug].js
访问它。
我尝试过的
我一直在使用 Apollo Client 来处理查询。我有一个连接到 API 的 apolloClient.js
文件:
// apolloClient.js
import ApolloClient, InMemoryCache from "@apollo/client";
export default new ApolloClient(
uri: "http://localhost:3000/admin/api",
cache: new InMemoryCache(),
);
我有一个post.service.js
文件来查询 API:
// post.service.js
import gql from "@apollo/client";
import apolloClient from "../_utils/apolloClient";
export async function getAll()
return apolloClient
.query(
query: gql`
query
allPosts
id
term
slug
`,
)
.then((result) => result.data.allPosts);
export async function getBySlug(slug)
return apolloClient
.query(
query: gql`
query
Post(slug: $slug)
id
title
lead
body
`,
)
.then((result) =>
return result.data.Post;
);
最后,在posts/[slug].js
,我试图像这样返回数据:
//[slug].js
import Head from "next/head";
import ApolloClient, InMemoryCache, gql from "@apollo/client";
import getAll, getBySlug from "../../_services/post.service";
export default function Post( post )
return (
<div>
<Head>
<title>Launchpad</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<main>
<h1>post.term</h1>
</main>
<footer>
<p>post.lead</p>
</footer>
</div>
);
export async function getStaticPaths()
const posts = await getAll();
const paths = posts.map((post) => (
params: id: post.slug ,
));
return paths, fallback: false ;
export async function getStaticProps( params )
const post = await getBySlug(params.id);
return props: post ;
显然,这是行不通的。我不能正确地将变量(我假设是 slug)传递到查询中,并且阅读了几个教程后,我仍然无法理解它。有谁知道我做错了什么?
【问题讨论】:
几件事:1)在getStaticPaths
中,您将await getAll()
保存到lingo
,但随后映射posts
变量,这是一个错字吗? 2) 在getStaticProps
中对getBySlug
调用执行相同的操作,使用term
变量但随后返回post
。
是的,从错误的文件中复制了代码,谢谢。我已经更新了原始问题中的代码。我也有同样的问题。什么都没有回来。
【参考方案1】:
在getStaticPaths
中,params
对象中返回的键需要匹配动态路由命名。在您的情况下,由于您使用posts/[slug].js
作为路线,您需要以 slug: post.slug
的格式返回params
。
export async function getStaticPaths()
const posts = await getAll();
const paths = posts.map((post) => (
params: slug: post.slug , // Rename to `slug`
));
return paths, fallback: false ;
export async function getStaticProps( params )
const post = await getBySlug(params.slug); // Rename to `params.slug`
return props: post ;
编辑:关于请求问题,对getBySlug
的以下更改应该可以使其按预期工作。
export async function getBySlug(slug)
return apolloClient
.query(
query: gql`
query Post($slug: String)
post(slug: $slug)
id
title
lead
body
`,
variables:
slug
)
.then((result) =>
return result.data.Post;
);
【讨论】:
谢谢。我已经更新了我的代码,但我得到了错误:Error: Response not successful: Received status code 400
。这表明我的查询在post.service.js
中是错误的?我的论点错了吗?
是的,这意味着请求有问题。
好的,谢谢!我将单独问一个关于如何通过 slug 查询 API 的问题,因为我不知道查询如何知道 slug 是什么。
这有帮助吗:***.com/a/51523848/1870780?您不应该将额外的variables
对象传递给apolloClient.query()
调用吗?请注意,我的 GraphQL 知识有限。
谢谢。是的,它帮助我更好地编写查询。我的查询仍然出现 Apollo 错误,因此我已向here 寻求帮助。以上是关于如何基于 GraphQL API 的 slug 使用 Next.js 进行动态路由?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 GraphQL 通过 slug 进行搜索? - 字段“文章”上的“未知参数”
如何在使用 graphql 和 mongodb 的查询中使用“where”参数?