Как я могу сделать POST-запрос к своему бэкэнду, используя RTK Query в NextJS 13, из новой папки API?
Как правильно инициировать запрос? Я пробовал следующие 2 способа отправки, и ни один из них не работал:
//first try
const dispatch = useDispatch<AppDispatch>();
dispatch(addMemoria.initiate({firstName, lastName, birthDate: selectedBirthDate, deathDate: selectedDeathDate}));
//second try
addMemoria.initiate({firstName, lastName, birthDate: selectedBirthDate, deathDate: selectedDeathDate});
Ожидаемым результатом будет успешный запрос POST и новая запись Memoria в базе данных.
Ошибка, которую я получаю:
hydration-error-info.js?32aa:27 An unhandled error occurred processing a request for the endpoint "addMemoria".
In the case of an unhandled error, no tags will be "provided" or "invalidated". Error: Invariant: Method expects to have requestAsyncStorage, none available
at headers (webpack-internal:///(:3000/e-memoria/app-client)/./node_modules/next/dist/client/components/headers.js:17:15)
at getServerSession (webpack-internal:///(:3000/e-memoria/app-client)/./node_modules/next-auth/next/index.js:94:35)
at prepareHeaders (webpack-internal:///(:3000/e-memoria/app-client)/./src/store/strapiApi.ts:23:90)
at eval (webpack-internal:///(:3000/e-memoria/app-client)/./node_modules/@reduxjs/toolkit/dist/query/rtk-query.esm.js:239:42)
at step (webpack-internal:///(:3000/e-memoria/app-client)/./node_modules/@reduxjs/toolkit/dist/query/rtk-query.esm.js:44:23)
at Object.eval [as next] (webpack-internal:///(:3000/e-memoria/app-client)/./node_modules/@reduxjs/toolkit/dist/query/rtk-query.esm.js:25:53)
Следующий почтовый запрос действителен с использованием моего http-клиента:
POST http://localhost:1337/api/memorias
Content-Type: application/json
authorization: Bearer ****************************
{
"data": {
"firstName": "FirstNAmeTest",
"lastName": "LAstNameTest",
"birthDate": "2021-09-01",
"deathDate": "2021-09-02"
}
}
Конфигурация магазина РТК:
export const store = configureStore({
reducer: {
strapiApi: strapiApi.reducer,
},
middleware(getDefaultMiddleware) {
return getDefaultMiddleware().concat(strapiApi.middleware);
},
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
Моя конечная точка API (авторизованный запрос GET работает):
const baseQuery = fetchBaseQuery({
baseUrl: process.env.STRAPI_API_URL + '/api/', //"http://localhost:3000/api/",
prepareHeaders: async (headers, { getState }) => {
const session : any = await getServerSession(authOptions);
// If we have a token set in state, let's assume that we should be passing it.
if (session) {
headers.set('authorization', `Bearer ${session?.jwt}`)
}
headers.set('cache', 'no-store');
headers.set('Cache-control', 'no-store, max-age=0');
return headers
},
})
export const strapiApi = createApi({
reducerPath: "strapiApi",
baseQuery: baseQuery,
tagTypes: ["Memoria", "bla"],
endpoints: (builder) => ({
getAllMemorias: builder.query<{ results: Array<{ name: string }> }, void>({
query: () => `memorias`,
providesTags: ['bla'],
}),
addMemoria: builder.mutation<Memoria, Partial<Memoria>>({
query: (body: Partial<Memoria>) => ({
url: `memorias`,
method: 'POST',
body: createStrapiPOSTBody(body),
}),
invalidatesTags: [{ type: 'Memoria', id: 'LIST' }],
}),
});
export const { getAllMemorias, addMemoria } = strapiApi.endpoints;
Насколько мне известно, вы можете вызывать getServerSession
только в компонентах React Server. У вас нет доступа к заголовкам внутри клиентских компонентов, которые обрабатываются на сервере. Похоже, вы прямо сейчас вызываете его из клиентского компонента.
Как правило, вы также не должны использовать что-то вроде export const
для магазина Redux в Next SSR, так как таким образом этот магазин будет использоваться несколькими пользователями. Tbh., нет хорошей истории о том, как все это сделать - это все еще очень экспериментально.
Даже файлы с «использованием запроса» будут выполняться на сервере и иметь эту проблему совместного использования глобальных переменных между запросами в дополнительном SSR, запускаемом после RSC. Для «традиционного» Next SSR это решает redux-next-wrapper
. Для каталога app
Next пока просто ничего нет. Имейте в виду, что здесь вы работаете с полностью экспериментальной технологией. Обязательно проведите много экспериментов и не запускайте ничего из этого в производственной среде, пока следующая команда не даст указаний о том, что это безопасно.
Или другими словами: экспериментировать приятно. Но если вы хотите создать какое-либо реальное приложение, не используйте каталог app
. Он помечен как экспериментальный по какой-то причине.
Уважаемый @phry, большое спасибо, что нашли время ответить на мой вопрос. Из вашего ответа я понял, что избыточность на стороне сервера не должна использоваться для каких-либо личных данных => никакие авторизованные вызовы API не должны выполняться с помощью RTK Q на сервере. Как посоветуете дальше поступить. Должен ли я делать редукцию только на стороне клиента и добавлять «использовать клиент» во все файлы моего магазина? Это означало бы, что вся платформа находится на стороне клиента. И я бы использовал только серверную часть, например, для блога, где люди должны выполнять только операции чтения. Лучший, Серджиу