如何基于 GraphQL API 的 slug 使用 Next.js 进行动态路由?

时间:2021-01-20 23:17:33

标签: reactjs graphql next.js apollo apollo-client

我很难理解基于变量的动态路由。我能够获取集合中的项目列表,但不能通过 Next.js 获取具有动态路由的单个页面的单个项目及其字段。

背景

我有一个带有 GraphQL API 的 KeystoneJS 无头 CMS。我正在尝试创建一个简单的博客,其中包含一个帖子列表和一个单独的帖子页面。我已经能够查询和返回帖子列表,但我需要根据 slug 字段获取单个帖子,以便可以在 /usr/lib/node_modules/dociql/node_modules/node-sass/lib/binding.js:13 throw new Error(errors.unsupportedEnvironment()); ^ Error: Node Sass does not yet support your current environment: Linux 64-bit with Unsupported runtime (88) For more information on which environments are supported please see: https://github.com/sass/node-sass/releases/tag/v4.14.1 at module.exports (/usr/lib/node_modules/dociql/node_modules/node-sass/lib/binding.js:13:13) at Object.<anonymous> (/usr/lib/node_modules/dociql/node_modules/node-sass/lib/index.js:14:35) at Module._compile (node:internal/modules/cjs/loader:1108:14) at Object.Module._extensions..js (node:internal/modules/cjs/loader:1137:10) at Module.load (/usr/lib/node_modules/dociql/node_modules/coffeescript/lib/coffeescript/register.js:53:36) at Function.Module._load (node:internal/modules/cjs/loader:813:14) at Module.require (node:internal/modules/cjs/loader:997:19) at require (node:internal/modules/cjs/helpers:92:18) at Object.<anonymous> (/usr/lib/node_modules/dociql/app/lib/config.js:2:14) at Module._compile (node:internal/modules/cjs/loader:1108:14) at Object.Module._extensions..js (node:internal/modules/cjs/loader:1137:10) at Module.load (/usr/lib/node_modules/dociql/node_modules/coffeescript/lib/coffeescript/register.js:53:36) at Function.Module._load (node:internal/modules/cjs/loader:813:14) at Module.require (node:internal/modules/cjs/loader:997:19) at require (node:internal/modules/cjs/helpers:92:18) at module.exports (/usr/lib/node_modules/dociql/index.js:61:18) at Object.<anonymous> (/usr/lib/node_modules/dociql/bin/dociql.js:40:1) at Module._compile (node:internal/modules/cjs/loader:1108:14) at Object.Module._extensions..js (node:internal/modules/cjs/loader:1137:10) at Module.load (node:internal/modules/cjs/loader:973:32) at Function.Module._load (node:internal/modules/cjs/loader:813:14) at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:76:12) at node:internal/main/run_main_module:17:47 处访问它。

我的尝试

我一直在使用 Apollo Client 来处理查询。我有一个连接到 API 的 /posts/[slug].js 文件:

apolloClient.js

我有一个 // apolloClient.js import { ApolloClient, InMemoryCache } from "@apollo/client"; export default new ApolloClient({ uri: "http://localhost:3000/admin/api", cache: new InMemoryCache(), }); 文件来查询 API:

post.service.js

最后,在 // 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)正确地传递到查询中,并且在阅读了几个教程后我仍然无法理解它。有没有人看到我做错了什么?

1 个答案:

答案 0 :(得分:0)

getStaticPaths 中,params 对象中返回的键需要匹配动态路由命名。就您而言,由于您使用 posts/[slug].js 作为路线,因此您需要以 params 格式返回 { slug: post.slug }

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;
    });
}
相关问题