Name:
interface
Value:
Amplify has re-imagined the way frontend developers build fullstack applications. Develop and deploy without the hassle.

Page updated Oct 1, 2025

Set up Amplify REST API

Using the AWS Cloud Development Kit (AWS CDK), you can configure Amplify Functions as resolvers for routes of a REST API powered by Amazon API Gateway.

Set up REST API with Lambda Function

Create a new directory and a resource file, amplify/functions/api-function/resource.ts. Then, define the function with defineFunction:

amplify/functions/api-function/resource.ts
import { defineFunction } from "@aws-amplify/backend";
export const myApiFunction = defineFunction({
name: "api-function",
});

Create the corresponding handler file, amplify/functions/api-function/handler.ts, file with the following contents:

amplify/functions/api-function/handler.ts
import type { APIGatewayProxyHandler } from "aws-lambda";
export const handler: APIGatewayProxyHandler = async (event) => {
console.log("event", event);
return {
statusCode: 200,
// Modify the CORS settings below to match your specific requirements
headers: {
"Access-Control-Allow-Origin": "*", // Restrict this to domains you trust
"Access-Control-Allow-Headers": "*", // Specify only the headers you need to allow
},
body: JSON.stringify("Hello from myFunction!"),
};
};

Use the AWS CDK to create an REST API resource powered by Amazon API Gateway.

amplify/backend.ts
import { defineBackend } from "@aws-amplify/backend";
import { Stack } from "aws-cdk-lib";
import {
AuthorizationType,
CognitoUserPoolsAuthorizer,
Cors,
LambdaIntegration,
RestApi,
} from "aws-cdk-lib/aws-apigateway";
import { Policy, PolicyStatement } from "aws-cdk-lib/aws-iam";
import { myApiFunction } from "./functions/api-function/resource";
import { auth } from "./auth/resource";
import { data } from "./data/resource";
const backend = defineBackend({
auth,
data,
myApiFunction,
});
// create a new API stack
const apiStack = backend.createStack("api-stack");
// create a new REST API
const myRestApi = new RestApi(apiStack, "RestApi", {
restApiName: "myRestApi",
deploy: true,
deployOptions: {
stageName: "dev",
},
defaultCorsPreflightOptions: {
allowOrigins: Cors.ALL_ORIGINS, // Restrict this to domains you trust
allowMethods: Cors.ALL_METHODS, // Specify only the methods you need to allow
allowHeaders: Cors.DEFAULT_HEADERS, // Specify only the headers you need to allow
},
});
// create a new Lambda integration
const lambdaIntegration = new LambdaIntegration(
backend.myApiFunction.resources.lambda
);
// create a new resource path with IAM authorization
const itemsPath = myRestApi.root.addResource("items", {
defaultMethodOptions: {
authorizationType: AuthorizationType.IAM,
},
});
// add methods you would like to create to the resource path
itemsPath.addMethod("GET", lambdaIntegration);
itemsPath.addMethod("POST", lambdaIntegration);
itemsPath.addMethod("DELETE", lambdaIntegration);
itemsPath.addMethod("PUT", lambdaIntegration);
// add a proxy resource path to the API
itemsPath.addProxy({
anyMethod: true,
defaultIntegration: lambdaIntegration,
});
// create a new Cognito User Pools authorizer
const cognitoAuth = new CognitoUserPoolsAuthorizer(apiStack, "CognitoAuth", {
cognitoUserPools: [backend.auth.resources.userPool],
});
// create a new resource path with Cognito authorization
const booksPath = myRestApi.root.addResource("cognito-auth-path");
booksPath.addMethod("GET", lambdaIntegration, {
authorizationType: AuthorizationType.COGNITO,
authorizer: cognitoAuth,
});
// create a new IAM policy to allow Invoke access to the API
const apiRestPolicy = new Policy(apiStack, "RestApiPolicy", {
statements: [
new PolicyStatement({
actions: ["execute-api:Invoke"],
resources: [
`${myRestApi.arnForExecuteApi("*", "/items", "dev")}`,
`${myRestApi.arnForExecuteApi("*", "/items/*", "dev")}`,
`${myRestApi.arnForExecuteApi("*", "/cognito-auth-path", "dev")}`,
],
}),
],
});
// attach the policy to the authenticated and unauthenticated IAM roles
backend.auth.resources.authenticatedUserIamRole.attachInlinePolicy(
apiRestPolicy
);
backend.auth.resources.unauthenticatedUserIamRole.attachInlinePolicy(
apiRestPolicy
);
// add outputs to the configuration file
backend.addOutput({
custom: {
API: {
[myRestApi.restApiName]: {
endpoint: myRestApi.url,
region: Stack.of(myRestApi).region,
apiName: myRestApi.restApiName,
},
},
},
});

Install Amplify Libraries

Use the package manager of your choice to install the Amplify JavaScript library. For example, with npm:

Terminal
npm add aws-amplify

Initialize Amplify API

Important: Custom REST APIs require explicit configuration. Unlike built-in Amplify resources (Auth, Data), custom APIs are not automatically included when calling Amplify.configure(outputs).

To initialize the Amplify API category you need to configure Amplify with Amplify.configure().

Import and load the configuration file in your app. It's recommended you add the Amplify configuration step to your app's root entry point. For example index.js in React or main.ts in Angular.

src/main.ts
import { Amplify } from 'aws-amplify';
import { parseAmplifyConfig } from "aws-amplify/utils";
import outputs from '../amplify_outputs.json';
const amplifyConfig = parseAmplifyConfig(outputs);
Amplify.configure(
{
...amplifyConfig,
API: {
...amplifyConfig.API,
REST: outputs.custom.API, // ← Required for custom REST APIs
},
},
{
API: {
REST: {
retryStrategy: {
strategy: 'no-retry', // Overrides default retry strategy
},
}
}
}
);

Make sure you call Amplify.configure as early as possible in your application’s life-cycle. A missing configuration or NoCredentials error is thrown if Amplify.configure has not been called before other Amplify JavaScript APIs. Review the Library Not Configured Troubleshooting guide for possible causes of this issue.

Critical Configuration Step: The line REST: outputs.custom.API is required to register your custom REST API. Without this, you'll encounter the error API name is invalid when trying to call your API.

Troubleshooting

"API name is invalid" Error

If you encounter the error API name is invalid when calling your REST API, ensure you have:

  1. Added the custom API configuration: Include REST: outputs.custom.API in your Amplify.configure() call
  2. Used the correct API name: The API name should match the restApiName defined in your backend.ts file
  3. Called Amplify.configure(): Make sure configuration happens before any API calls

Example of incorrect configuration (missing custom API):

// ❌ This will cause "API name is invalid" error
Amplify.configure(outputs); // Missing custom REST API configuration

Correct configuration:

// ✅ This includes custom REST APIs
const amplifyConfig = parseAmplifyConfig(outputs);
Amplify.configure({
...amplifyConfig,
API: {
...amplifyConfig.API,
REST: outputs.custom.API, // Required for custom APIs
},
});