【问题标题】:prettier urls with nextjs routes带有 nextjs 路由的更漂亮的 url
【发布时间】:2021-08-03 21:28:43
【问题描述】:

我正在使用next.js 为我的公司建立一个新的营销网站,但遇到了URLS 问题。本质上,我使用 Prisma 构建了一个自定义 API 路由来访问我们内部数据库中的数据:

getAllDealers.ts

import Cors from 'cors';
import { prisma } from 'lib/prisma';
import { NextApiResponse, NextApiRequest, NextApiHandler } from 'next';

const cors = Cors({
  methods: ['GET', 'HEAD'],
});

function runMiddleware(req: NextApiRequest, res: NextApiResponse, fn: any) {
  return new Promise((resolve, reject) => {
    fn(req, res, (result: any) => {
      if (result instanceof Error) {
        return reject(result);
      }

      return resolve(result);
    });
  });
}

const getDealers: NextApiHandler = async (req: NextApiRequest, res: NextApiResponse) => {
  const { method } = req;

  await runMiddleware(req, res, cors);
  const dealers = await prisma.crm_dealers.findMany({
    where: {
      active: {
        not: 0,
      },
    },
  });

  switch (method) {
    case 'GET':
      res.status(200).send({ dealers, method: method });
      break;
    case 'PUT':
      res.status(500).json({ message: 'sorry, we only accept GET requests', method: method });
      break;
    default:
      res.setHeader('Allow', ['GET']);
      res.status(405).end(`Method ${method} Not Allowed`);
  }
};

export default getDealers;

而且我已经建立了访问各个经销商的途径:

getSingleDealer.ts

import Cors from 'cors';
import { prisma } from 'lib/prisma';
import { NextApiResponse, NextApiRequest, NextApiHandler } from 'next';

const cors = Cors({
  methods: ['GET', 'HEAD'],
});

function runMiddleware(req: NextApiRequest, res: NextApiResponse, fn: any) {
  return new Promise((resolve, reject) => {
    fn(req, res, (result: any) => {
      if (result instanceof Error) {
        return reject(result);
      }

      return resolve(result);
    });
  });
}

const getDealerById: NextApiHandler = async (req: NextApiRequest, res: NextApiResponse) => {
  await runMiddleware(req, res, cors);
  const dealer = await prisma.crm_dealers.findUnique({
    where: {
      id: Number(req.query.id),
    },
  });

  res.status(200).send({ dealer, method: req.method });
};

export default getDealerById;

我可以像这样在getServerSideProps 中使用我的getSingleDealer 函数:

export const getServerSideProps = async ({ params }: Params) => {
  const { uid } = params;

  const { dealer } = await getSingleDealer('api/dealer', uid);

  return {
    props: { dealer },
  };
};

这很好用。我需要做的是美化我的 URLS。现在,访问单个经销商页面的方法是dealers/1,其中 1 是经销商的 ID。我希望该 URL 是一个字符串,例如 dealers/sacramento-ca(该位置也在 API 中提供),同时仍然基于 id 访问 API,因此它正在搜索整数,而不是字符串。下一个有可能吗?

【问题讨论】:

    标签: reactjs next.js api-design


    【解决方案1】:

    您将使用getServerSideProps 处理客户端中的路由,类似于您现在正在做的事情。为此,您需要配置您的 dynamic routing 文件或文件夹名称以匹配您所需的格式。

    文件夹结构示例如下:

    pages > dealers > [dealer].tsx = /dealers/sacramento-ca

    pages > dealers > [location] > index.tsx = /dealers/sacramento-ca

    export const getServerSideProps = async ({ params }: Params) => {
      const { uid } = params;
      const { dealer } = await getSingleDealer('api/dealer', uid);
    
      if (!dealer ) {
        return { notFound: true }
      }
    
      return {
        props: { 
         ...dealer,
         location: 'sacramento-ca', // object key must match your dynamic [folder or file's name]
        },
      };
    };
    

    所有动态 URL 部分都必须作为键包含在返回中。

    pages > dealers > [state] > index.tsx [city].tsx = /dealers/ca/sacramento

    return {
      props: {
       ...dealer,
       city: 'sacramento',
       state: 'ca',
      },
    };
    

    这是article,详细说明了您需要做什么。请务必注意,有时需要使用 catch all route 来简化搜索和深度嵌套的动态路由。

    【讨论】:

    • 我以前用过catch all routes,不知道为什么我没想到。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-02
    • 2014-09-24
    • 2013-07-09
    • 1970-01-01
    • 1970-01-01
    • 2018-04-06
    相关资源
    最近更新 更多