Closed didemkkaslan closed 3 months ago
Hi @didemkkaslan Looking at the code examples you have provided (thanks for the detailed comments!), that you configured your REST API via Amplify.configure()
in the client component ConfigureAmplifyClientSide
. This means you can only use the configured REST API on the client side. And you are forcefully calling the REST API within a Server Component, it will throw this error as the configuration is not applied on the server side at all.
If you are aiming to use the REST API on the server side in a Server Component, you need to do the following:
createServerRunner()
, and use the runWithAmplifyServerContext
function along with the server REST APIs exported from aws-amplify/api/server
getCognitoAuthIDToken
implementation to use the server fetchAuthSession
API exported from aws-amplify/auth/server
See this documentation for details about using the Amplify server-side APIs.
Thanks @HuiSF Ive made these changes:
users/page.tsx
const users = await runWithAmplifyServerContext({
nextServerContext: { cookies },
operation: async (contextSpec) => {
const result = await PlatformCoreOldRestApi.get<UserData[]>(
contextSpec,
`/platform/people/search?email=${query}`
);
return result;
},
});
AmplifyServerUtils.tsx
import { createServerRunner } from "@aws-amplify/adapter-nextjs";
import { ResourcesConfig } from "aws-amplify";
export const amplifyResourceConfig: ResourcesConfig = {
Auth: {
Cognito: {
userPoolId: String(process.env.NEXT_PUBLIC_USER_POOL_ID),
userPoolClientId: String(process.env.NEXT_PUBLIC_USER_POOL_CLIENT_ID),
},
},
API: {
REST: {
PlatformCoreOldRestApi: {
endpoint: `${String(
process.env.NEXT_PUBLIC_PLATFORM_CORE_OLD_REST_API_URL
)}`,
},
PlatformCoreNewRestApi: {
endpoint: `${String(
process.env.NEXT_PUBLIC_PLATFORM_CORE_NEW_REST_API_URL
)}`,
},
},
},
};
export const { runWithAmplifyServerContext } = createServerRunner({
config: amplifyResourceConfig,
});
RestAPIs.ts
import { get, del } from "aws-amplify/api/server";
export function platformAPI({ apiName }: { apiName: string }) {
console.log("apiName:", apiName);
return {
get: async <T>(contextSpec, path: string) =>
get(contextSpec, {
apiName,
path,
}).response.then(async (res) => (await res.body.json()) as T),
delete: async <T>(path: string, queryParams?: Record<string, string>) =>
del({
apiName,
path,
options: {
queryParams: queryParams || undefined,
},
}).response.then(async (res) => (await res.statusCode) as T),
};
}
export const PlatformCoreOldRestApi = platformAPI({
apiName: "PlatformCoreOldRestApi",
});
export const PlatformCoreNewRestApi = platformAPI({
apiName: "PlatformCoreNewRestApi",
});
But I'm getting unauthorized error is there anything I should also do? Maybe its because I don't have this API REST Headers setup with Authorization header
Amplify.configure(amplifyResourceConfig, {
ssr: true,
API: {
REST: {
headers: async () => ({
Authorization: `Bearer ${await getCognitoAuthIDToken()}`,
}),
},
},
});
but I couldnt do the same thing with createServerRunner because importing fetchAuthSession from @aws-amplify/auth/server now it also needs contextspec as param
export const { runWithAmplifyServerContext } = createServerRunner({
config: amplifyResourceConfig,
});
Hmm this code actually worked:
const users = await runWithAmplifyServerContext({
nextServerContext: { cookies },
operation: async (contextSpec) => {
const session = await fetchAuthSession(contextSpec);
const token = session.tokens?.idToken?.toString() as string;
const result = await PlatformCoreOldRestApi.get<UserData[]>(
contextSpec,
`/platform/people/search?email=${query}`,
{
headers: {
Authorization: `Bearer ${token}`,
},
}
);
return result;
},
});
Hi @didemkkaslan thanks for the additional information. Your latest solution would be something that I recommend to do.
Amplify server-side APIs have to be running inside the isolated context that's created by runWithAmplifyServerContext
per incoming request, resolving the auth tokens along each REST API call compliance this pattern.
Please let us know is there anything else we can help.
Hello @HuiSF my problem is solved thanks for the support 😻
Before opening, please confirm:
JavaScript Framework
Next.js
Amplify APIs
REST API
Amplify Version
v6
Amplify Categories
api
Backend
CDK
Environment information
Describe the bug
Hello I'm using amplify v6 in nextjs app router and when I try to use rest api then I get API name is invalid error only if I try to use it in a server component. It works well with client components like useQuery, useSWR or classical useeffect fetch
Expected behavior
I'm not so sure If I'm doing it right way but it should fetch the data in server components too
Reproduction steps
Call rest api in a server component
Code Snippet
Please help me I couldn't find a resource where I can set up nextjs with app router + amplify v6. The current one uses graphql api so I'm kind of stuck
Log output
aws-exports.js
No response
Manual configuration
No response
Additional configuration
No response
Mobile Device
No response
Mobile Operating System
No response
Mobile Browser
No response
Mobile Browser Version
No response
Additional information and screenshots
No response