#javascript #node.js #next.js
#javascript #node.js #next.js
Вопрос:
У меня сложилось впечатление, что вы можете импортировать обработчики запросов api и вызывать их непосредственно внутри вашей функции getStaticProps из-за документации, в которой говорится:
Примечание: вы не должны использовать fetch() для вызова маршрута API в вашем приложении. Вместо этого напрямую импортируйте маршрут API и вызывайте его функцию самостоятельно. Возможно, вам потребуется немного реорганизовать ваш код для этого подхода.
У меня есть маршрут api /api/user/[id].js
, и реализация выглядит примерно так:
export default function user(req, res) {
const userId = req.query.id;
const user = getUserById(userId);
res.json(user);
}
Если я хочу использовать этот обработчик на getStaticProps
другой странице во внешнем интерфейсе, например /admin/user/[id].js
, как мне передать id
запрос обработчику запроса? Вызов его без каких-либо параметров не работает и выдает сообщение об ошибке, которое req.query.id
не определено.
import userHandler from "../../api/user/[id].js";
export async getStaticProps(){
// This is where the api handler is getting called
const user = await userHandler();
return { props: { user } }
}
Ответ №1:
Вот что я бы посоветовал сделать, чтобы заставить материал работать:
- вам не нужно «динамическое» имя для файла с вашими обработчиками вызовов api (вместо
/api/user/[id].js
вы можете создать/api/user.js
); - вам необходимо указать страницу (файл) для просмотра сведений о пользователе. Он должен быть создан в
/pages/user/[id].js
и вставитьgetStaticProps
туда функцию. Теперь, как только вы измените URL-адрес в браузереhttp://localhost:3000/user/whatever
getStaticProps
, будет вызываться с помощью ({ params: {id: ‘whatever’}})
getStaticProps
— получает context
аргумент, который состоит из нескольких свойств. Все части динамического URL будут сохранены в params
свойстве, принимая во внимание вышеуказанную часть, это должно сработать:
export async getStaticProps({ params }){
const user = await user(params.id);
return { props: { user } }
}
Если вам нужно какое-то дополнительное объяснение, вы можете спросить
Комментарии:
1. Я переименовал обработчик запроса из
user
вuserHandler
, так как понял, что дважды использовал это имяuser
в своем примере. Ваш вариант кажется правильным, но я бы просто внес исправление, которое вы, вероятно, хотели написатьawait userHandler({ query: params })
, потому что обработчик ожидает объект запроса, а не сам идентификатор. Он отвечает на вопрос, но я не знаю, является ли это доказательством на будущее, поскольку он включает отправку поддельного объекта запроса без большого количества значений, которые обычно находятся в объекте запроса.2. Похоже, что правильный способ вызова обработчика API использует
fetch
вместо прямого импорта обработчика, в таком случае начальное имя файла для обработчика правильное :/pages/api/user/[id].js
. Теперь, когда вы вызываетеfetch
изgetStaticProps
, вы должны указать URL-адрес, аналогичный структуре папок обработчика:const user = await fetch('/api/user/whatever')
.
Ответ №2:
Вы не должны вызывать конечную точку API внутренне на сервере. user()
Обработчик в вашем API требует Request
, Response
чтобы объекты and передавались в качестве аргументов, и нет смысла подделывать HTTP-запрос / ответ.
Вместо export
этого функция, которую ваш API использует для получения пользовательских данных: getUserById(userId)
. Затем import
и вызовите его getStaticProps()
.
Комментарии:
1. Это то, о чем я тоже думал, но я просто хотел еще немного покопаться, чтобы убедиться, что нет другой альтернативы на случай, если у меня есть обработчик API с большой логикой. В таких ситуациях я бы предпочел иметь возможность повторно использовать логику из обработчика, чем переписывать ее в getStaticProps, но я не думаю, что это выполнимо без подделки объекта req.