1. Docs
  2. Pulumi IaC
  3. Clouds
  4. AWS
  5. Guides
  6. API Gateway

Amazon API Gateway

    Amazon API Gateway is a fully managed service for creating, monitoring, and securing APIs at scale. It acts as a “front door” for REST and WebSocket applications that use backend services, and handles all the tasks necessary to accept and process up to hundreds of thousands of concurrent API calls, including traffic management, authorization and access control, monitoring, and API version management. API Gateway is inexpensive, has no minimum fees, and you only pay for the API calls you receive and the data transferred out.

    Overview

    Pulumi Crosswalk for Amazon Web Services (AWS) provides better AWS API management through significantly easier ways of programming an API Gateway. This includes using infrastructure as code techniques for simple, declarative APIs, including easy Lambda integration.

    The examples below all use the AWS API Gateway component to configure API Gateway to serve several common scenarios. For more information about how to install and use this component, see its full documentation in the Pulumi Registry.

    Creating and configuring routes

    AWS API Gateway creates REST APIs that:

    • Are HTTP based.
    • Adhere to the REST protocol.
    • Implement standard HTTP methods such as GET, POST, PUT, PATCH, and DELETE.

    Each API Gateway instance defines a new API endpoint and a collection of API routes, each of which has a distinct URL.

    Internally the API Gateway resource uses a collection of supporting objects, like resources, methods, and more, however one of the benefits of Pulumi Crosswalk for AWS is that it hides these mechanics behind a simpler interface.

    Each API Gateway deployment is associated with a stage. A stage is a version of your API, such as stage, prod, v1, or v2. For simple APIs, you will likely just have one. You can always define a custom stage name, but if you leave it off, a default of stage will be chosen.

    API Gateway will auto-generate a domain name with built-in HTTPS support. The stage name will also be part of this URL. You’ll see later how to assign a custom domain, SSL certificate, and/or eliminate the stage name from the URL.

    There are multiple ways to define APIs using Pulumi Crosswalk for AWS:

    Multiple endpoints on the same API Gateway can be defined using a combination of these techniques.

    Handling requests with Lambda

    An event-handler route is an API that will map to a Lambda function. You specify the path, HTTP method, and the Lambda function to invoke when the API is called. Pulumi offers multiple ways of defining the Lambda function and it provisions the appropriate permissions so that API Gateway can communicate with it.

    This example creates an Amazon API Gateway REST API with a single API endpoint, listening at / for GET requests and a 200 OK for each call.

    "use strict";
    const aws = require("@pulumi/aws");
    const apigateway = require("@pulumi/aws-apigateway");
    
    // A Lambda function to invoke.
    const handler = new aws.lambda.CallbackFunction("handler", {
        callback: async (event, context) => {
            return {
                statusCode: 200,
                body: JSON.stringify({
                    message: "Hello from API Gateway!",
                }),
            };
        },
    });
    
    // A REST API to route requests to the Lambda function.
    const api = new apigateway.RestAPI("api", {
        routes: [
            {
                path: "/",
                method: "GET",
                eventHandler: handler,
            },
        ],
    });
    
    // The URL at which the REST API will be served.
    exports.url = api.url;
    
    import * as aws from "@pulumi/aws";
    import * as apigateway from "@pulumi/aws-apigateway";
    
    // A Lambda function to invoke.
    const handler = new aws.lambda.CallbackFunction("handler", {
        callback: async (event, context) => {
            return {
                statusCode: 200,
                body: JSON.stringify({
                    message: "Hello from API Gateway!",
                }),
            };
        },
    });
    
    // A REST API to route requests to the Lambda function.
    const api = new apigateway.RestAPI("api", {
        routes: [
            {
                path: "/",
                method: "GET",
                eventHandler: handler,
            },
        ],
    });
    
    // The URL at which the REST API will be served.
    export const url = api.url;
    
    import json
    import pulumi
    import pulumi_aws as aws
    import pulumi_aws_apigateway as apigateway
    
    # An execution role to use for the Lambda function.
    role = aws.iam.Role(
        "role",
        assume_role_policy=json.dumps(
            {
                "Version": "2012-10-17",
                "Statement": [
                    {
                        "Action": "sts:AssumeRole",
                        "Effect": "Allow",
                        "Principal": {
                            "Service": "lambda.amazonaws.com",
                        },
                    }
                ],
            }
        ),
        managed_policy_arns=[aws.iam.ManagedPolicy.AWS_LAMBDA_BASIC_EXECUTION_ROLE],
    )
    
    # A Lambda function to invoke.
    handler = aws.lambda_.Function(
        "handler",
        runtime="python3.9",
        handler="handler.handler",
        role=role.arn,
        code=pulumi.FileArchive("./function"),
    )
    
    # A REST API to route requests to the Lambda function.
    api = apigateway.RestAPI(
        "api",
        routes=[
            apigateway.RouteArgs(
                path="/", method=apigateway.Method.GET, event_handler=handler
            )
        ],
    )
    
    # The URL at which the REST API will be served.
    pulumi.export("url", api.url)
    
    package main
    
    import (
    	"encoding/json"
    
    	"github.com/pulumi/pulumi-aws-apigateway/sdk/v2/go/apigateway"
    	"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/iam"
    	"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/lambda"
    	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
    )
    
    func main() {
    	pulumi.Run(func(ctx *pulumi.Context) error {
    
    		policy, err := json.Marshal(map[string]interface{}{
    			"Version": "2012-10-17",
    			"Statement": []map[string]interface{}{
    				{
    					"Action": "sts:AssumeRole",
    					"Effect": "Allow",
    					"Principal": map[string]interface{}{
    						"Service": "lambda.amazonaws.com",
    					},
    				},
    			},
    		})
    		if err != nil {
    			return err
    		}
    
    		// An execution role to use for the Lambda function.
    		role, err := iam.NewRole(ctx, "role", &iam.RoleArgs{
    			AssumeRolePolicy: pulumi.String(policy),
    			ManagedPolicyArns: pulumi.StringArray{
    				iam.ManagedPolicyAWSLambdaBasicExecutionRole,
    			},
    		})
    		if err != nil {
    			return err
    		}
    
    		// A Lambda function to invoke.
    		handler, err := lambda.NewFunction(ctx, "handler", &lambda.FunctionArgs{
    			Runtime: pulumi.String("python3.9"),
    			Handler: pulumi.String("handler.handler"),
    			Role:    role.Arn,
    			Code:    pulumi.NewFileArchive("./function"),
    		})
    		if err != nil {
    			return err
    		}
    
    		// A REST API to route requests to the Lambda function.
    		method := apigateway.MethodGET
    		api, err := apigateway.NewRestAPI(ctx, "api", &apigateway.RestAPIArgs{
    			Routes: []apigateway.RouteArgs{
    				{
    					Path: "/", Method: &method, EventHandler: handler,
    				},
    			},
    		})
    		if err != nil {
    			return err
    		}
    
    		// The URL at which the REST API will be served.
    		ctx.Export("url", api.Url)
    		return nil
    	})
    }
    
    using System.Collections.Generic;
    using System.Text.Json;
    using Pulumi;
    using Aws = Pulumi.Aws;
    using AwsApiGateway = Pulumi.AwsApiGateway;
    
    return await Deployment.RunAsync(() =>
    {
        // An execution role to use for the Lambda function.
        var role = new Aws.Iam.Role("role", new()
        {
            AssumeRolePolicy = JsonSerializer.Serialize(new Dictionary<string, object?>
            {
                ["Version"] = "2012-10-17",
                ["Statement"] = new[]
                {
                    new Dictionary<string, object?>
                    {
                        ["Action"] = "sts:AssumeRole",
                        ["Effect"] = "Allow",
                        ["Principal"] = new Dictionary<string, object?>
                        {
                            ["Service"] = "lambda.amazonaws.com",
                        },
                    },
                },
            }),
            ManagedPolicyArns = new[]
            {
                Aws.Iam.ManagedPolicy.AWSLambdaBasicExecutionRole.ToString(),
            },
        });
    
        // A Lambda function to invoke.
        var handler = new Aws.Lambda.Function("handler", new()
        {
            Runtime = "python3.9",
            Handler = "handler.handler",
            Role = role.Arn,
            Code = new FileArchive("./function"),
        });
    
        // A REST API to route requests to the Lambda function.
        var api = new AwsApiGateway.RestAPI("api", new()
        {
            Routes =
            {
                new AwsApiGateway.Inputs.RouteArgs
                {
                    Path = "/",
                    Method = AwsApiGateway.Method.GET,
                    EventHandler = handler,
                },
            },
        });
    
        return new Dictionary<string, object?>
        {
            // The URL at which the REST API will be served.
            ["url"] = api.Url,
        };
    });
    
    package myproject;
    
    import java.util.List;
    
    import com.pulumi.Pulumi;
    import com.pulumi.aws.iam.Role;
    import com.pulumi.aws.iam.RoleArgs;
    import com.pulumi.aws.iam.enums.ManagedPolicy;
    import com.pulumi.awsapigateway.enums.Method;
    import com.pulumi.aws.lambda.Function;
    import com.pulumi.aws.lambda.FunctionArgs;
    import com.pulumi.awsapigateway.RestAPI;
    import com.pulumi.awsapigateway.RestAPIArgs;
    import com.pulumi.awsapigateway.inputs.RouteArgs;
    import static com.pulumi.codegen.internal.Serialization.*;
    
    public class App {
        public static void main(String[] args) {
            Pulumi.run(ctx -> {
    
                // An execution role to use for the Lambda function.
                var role = new Role("role", RoleArgs.builder()
                    .assumeRolePolicy(serializeJson(
                        jsonObject(
                            jsonProperty("Version", "2012-10-17"),
                            jsonProperty("Statement", jsonArray(jsonObject(
                                jsonProperty("Action", "sts:AssumeRole"),
                                jsonProperty("Effect", "Allow"),
                                jsonProperty("Sid", ""),
                                jsonProperty("Principal", jsonObject(
                                    jsonProperty("Service", "lambda.amazonaws.com")
                                ))
                            )))
                        )))
                    .managedPolicyArns(List.of(ManagedPolicy.AWSLambdaBasicExecutionRole.getValue()))
                    .build());
    
                // An execution role to use for the Lambda function.
                var handler = new Function("handler", FunctionArgs.builder()
                    .runtime("python3.9")
                    .handler("handler.handler")
                    .role(role.arn())
                    .code(new com.pulumi.asset.FileArchive("./function"))
                    .build());
    
                // An execution role to use for the Lambda function.
                var api = new RestAPI("api", RestAPIArgs.builder()
                    .routes(new RouteArgs[]{
                        RouteArgs.builder()
                            .path("/")
                            .method(Method.GET)
                            .eventHandler(handler)
                            .build(),
                    })
                    .build());
    
                // An execution role to use for the Lambda function.
                ctx.export("url", api.url());
            });
        }
    }
    
    name: awsx-apigateway-lambda-yaml
    runtime: yaml
    description: An example that deploys an API Gateway REST API with a single endpoint backed by AWS Lambda.
    resources:
      # The URL at which the REST API will be served.
      role:
        type: aws:iam:Role
        properties:
          assumeRolePolicy:
            fn::toJSON:
              Version: "2012-10-17"
              Statement:
                - Action: sts:AssumeRole
                  Effect: Allow
                  Principal:
                    Service: lambda.amazonaws.com
          managedPolicyArns:
            - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
    
      # The URL at which the REST API will be served.
      handler:
        type: aws:lambda:Function
        properties:
          runtime: python3.9
          handler: handler.handler
          role: ${role.arn}
          code:
            fn::fileArchive: ./function
    
      # The URL at which the REST API will be served.
      api:
        type: aws-apigateway:RestAPI
        properties:
          routes:
            - path: /
              method: GET
              eventHandler: ${handler}
    
    outputs:
      # The URL at which the REST API will be served.
      url: ${api.url}
    

    Route paths can also be parameterized to allow for matching specific patterns:

    • A literal pattern like /pets will only match /pets
    • A parameterized pattern like /pets/{petId} will match child routes such as /pet/123
    • A wildcard pattern specified with {proxy+} like /pets/{proxy+} will match all descendant paths such as /pets/tagged/cuddly

    Running pulumi up provisions the API Gateway and its routes and returns the URL:

    $ pulumi up -y
    
    Updating (dev)
    
         Type                             Name                        Status
     +   pulumi:pulumi:Stack              awsx-apigateway-lambda-dev  created (25s)
     +   ├─ aws:iam:Role                  handler                     created (1s)
     +   ├─ aws:lambda:Function           handler                     created (14s)
     +   ├─ aws:iam:RolePolicyAttachment  handler-d32a66fa            created (0.82s)
     +   ├─ aws:iam:RolePolicyAttachment  handler-019020e7            created (1s)
     +   ├─ aws:iam:RolePolicyAttachment  handler-1b4caae3            created (1s)
     +   ├─ aws:iam:RolePolicyAttachment  handler-7cd09230            created (1s)
     +   ├─ aws:iam:RolePolicyAttachment  handler-b5aeb6b6            created (1s)
     +   ├─ aws:iam:RolePolicyAttachment  handler-4aaabb8e            created (1s)
     +   ├─ aws:iam:RolePolicyAttachment  handler-e1a3786d            created (1s)
     +   ├─ aws:iam:RolePolicyAttachment  handler-74d12784            created (1s)
     +   ├─ aws:iam:RolePolicyAttachment  handler-a1de8170            created (1s)
     +   └─ aws-apigateway:index:RestAPI  api                         created (6s)
     +      ├─ aws:apigateway:RestApi     api                         created (2s)
     +      ├─ aws:apigateway:Deployment  api                         created (0.42s)
     +      ├─ aws:lambda:Permission      api-fa520765                created (0.48s)
     +      └─ aws:apigateway:Stage       api                         created (0.54s)
    
    Outputs:
        url: "https://a5yj5n7rz0.execute-api.us-west-2.amazonaws.com/stage/"
    
    Resources:
        + 17 created
    
    Duration: 26s
    

    You can curl the exported URL to see that it’s up and running:

    $ curl $(pulumi stack output url)
    {"message":"Hello from API Gateway!"}%
    

    For more complete information about creating Lambda Functions, see the Pulumi Crosswalk for AWS Lambda documentation.

    Serving static files from S3

    A Static Route serves static content from S3 at an API endpoint.

    With the API Gateway component, you specify a local path (either a file or an entire directory), and the component manages the creation of the S3 bucket and the synchronization of the files to S3 objects.

    Given a directory www containing an index.html file, the following program creates an API Gateway API that serves the file at the root path (/) of the stage endpoint:

    "use strict";
    const apigateway = require("@pulumi/aws-apigateway");
    
    const api = new apigateway.RestAPI("api", {
        routes: [
            {
                path: "/",
                localPath: "www",
            },
        ],
    });
    
    exports.url = api.url;
    
    import * as apigateway from "@pulumi/aws-apigateway";
    
    const api = new apigateway.RestAPI("api", {
        routes: [
            {
                path: "/",
                localPath: "www",
            },
        ],
    });
    
    export const url = api.url;
    
    import pulumi
    import pulumi_aws as aws
    import pulumi_aws_apigateway as apigateway
    
    api = apigateway.RestAPI(
        "api",
        routes=[
            apigateway.RouteArgs(
                path="/",
                method=apigateway.Method.GET,
                local_path="www",
            )
        ],
    )
    
    pulumi.export("url", api.url)
    
    package main
    
    import (
    	"github.com/pulumi/pulumi-aws-apigateway/sdk/v2/go/apigateway"
    	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
    )
    
    func main() {
    	pulumi.Run(func(ctx *pulumi.Context) error {
    
    		api, err := apigateway.NewRestAPI(ctx, "api", &apigateway.RestAPIArgs{
    			Routes: []apigateway.RouteArgs{
    				{
    					Path:      "/",
    					LocalPath: pulumi.StringRef("www"),
    				},
    			},
    		})
    		if err != nil {
    			return err
    		}
    
    		ctx.Export("url", api.Url)
    		return nil
    	})
    }
    
    using System.Collections.Generic;
    using Pulumi;
    using AwsApiGateway = Pulumi.AwsApiGateway;
    
    return await Deployment.RunAsync(() =>
    {
        var api = new AwsApiGateway.RestAPI("api", new()
        {
            Routes =
            {
                new AwsApiGateway.Inputs.RouteArgs
                {
                    Path = "/",
                    LocalPath = "www",
                },
            },
        });
    
        return new Dictionary<string, object?>
        {
            ["url"] = api.Url,
        };
    });
    
    package myproject;
    
    import com.pulumi.Pulumi;
    import com.pulumi.awsapigateway.enums.Method;
    import com.pulumi.awsapigateway.RestAPI;
    import com.pulumi.awsapigateway.RestAPIArgs;
    import com.pulumi.awsapigateway.inputs.RouteArgs;
    
    public class App {
        public static void main(String[] args) {
            Pulumi.run(ctx -> {
    
                var api = new RestAPI("api", RestAPIArgs.builder()
                    .routes(new RouteArgs[]{
                        RouteArgs.builder()
                            .path("/")
                            .method(Method.GET)
                            .localPath("www")
                            .build(),
                    })
                    .build());
    
                ctx.export("url", api.url());
            });
        }
    }
    
    name: awsx-apigateway-s3-yaml
    runtime: yaml
    description: An example that uses API Gateway to serve static content from Amazon S3.
    
    resources:
      api:
        type: aws-apigateway:RestAPI
        properties:
          routes:
            - path: /
              localPath: www
    
    outputs:
      url: ${api.url}
    

    Again, after running pulumi up, you can curl the exported URL:

    $ curl $(pulumi stack output url)
    <html>
        <body>
            <p>Hello from API Gateway + S3!</p>
        </body>
    </html>
    

    By default, any index documents will be automatically served by S3 when directories are retrieved over HTTP. (See Configuring an Index Document in the AWS documentation for more information.) To suppress this behavior in the static route, set the index property to false. To use a different default document name, set index property to the name of the file you’d like to use, such as default.html.

    If the local path points to a directory, the route will automatically be created as a proxy path (i.e. /{proxy+}) to match all sub-directories and the content type for all files will be inferred automatically. If the local path points to a single file, you can specify the content type explicitly using the contentType property.

    Integrating with other AWS services

    If neither of the above route types work for you, Amazon API Gateway integrations connect an API Gateway endpoint to backend services that will execute code in response to requests. The previous Lambda and S3 examples use API Gateway integrations internally, even if it’s not evident in the simple interface exposed. Integrations give you full control over how HTTP requests are handled, and responses served, by an API Gateway route.

    If you want more flexibility than the earlier methods — e.g., to proxy HTTP requests, integrate with other AWS services, or mock your APIs — you can create an integration route by specifying the target property on your route.

    An integration route is a route that maps an endpoint to a specified backend. Supported integration route types include:

    • aws: Allows an API to expose an AWS service action, such as invoking Amazon Lambda Functions, Amazon DynamoDB, Amazon Simple Notification Service, or Amazon Simple Queue Service. You must configure the data mappings between the HTTP and underlying AWS service requests and responses.

    • aws_proxy: Also allows an API expose an AWS service action, but instead passes the HTTP request (including headers, path, query parameters, and body) directly to the underlying action.

    • http: Allows an API to expose HTTP endpoints with custom integration requests and responses. You must configure the data mappings between the HTTP and underlying AWS service requests and responses.

    • http_proxy: Allows an API to expose HTTP endpoints with a streamlined integration, without requiring you to configure the custom data mappings as with the http type.

    • mock: Allows API Gateway to return a response without sending a request to the backend. This is useful for API testing without needing to configure any backend to handle requests.

    The following example sets up an http_proxy integration that passes requests directly to another endpoint, in this case https://www.example.com:

    "use strict";
    const apigateway = require("@pulumi/aws-apigateway");
    
    const api = new apigateway.RestAPI("api", {
        routes: [
            {
                path: "/",
                target: {
                    type: "http_proxy",
                    uri: "https://www.example.com/",
                },
            },
        ],
    });
    
    exports.url = api.url;
    
    import * as apigateway from "@pulumi/aws-apigateway";
    
    const api = new apigateway.RestAPI("api", {
        routes: [
            {
                path: "/",
                target: {
                    type: "http_proxy",
                    uri: "https://www.example.com/",
                },
            },
        ],
    });
    
    export const url = api.url;
    
    import pulumi
    import pulumi_aws_apigateway as apigateway
    
    api = apigateway.RestAPI(
        "api",
        routes=[
            apigateway.RouteArgs(
                path="/",
                method=apigateway.Method.GET,
                target=apigateway.TargetArgs(
                    type="http_proxy",
                    uri="https://www.example.com/",
                ),
            ),
        ],
    )
    
    pulumi.export("url", api.url)
    
    package main
    
    import (
    	"github.com/pulumi/pulumi-aws-apigateway/sdk/v2/go/apigateway"
    	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
    )
    
    func main() {
    	pulumi.Run(func(ctx *pulumi.Context) error {
    
    		api, err := apigateway.NewRestAPI(ctx, "api", &apigateway.RestAPIArgs{
    			Routes: []apigateway.RouteArgs{
    				{
    					Path: "/",
    					Target: &apigateway.TargetArgs{
    						Type: apigateway.IntegrationType_Http_proxy,
    						Uri:  pulumi.String("https://www.example.com/"),
    					},
    				},
    			},
    		})
    		if err != nil {
    			return err
    		}
    
    		ctx.Export("url", api.Url)
    		return nil
    	})
    }
    
    using System.Collections.Generic;
    using Pulumi;
    using AwsApiGateway = Pulumi.AwsApiGateway;
    
    return await Deployment.RunAsync(() =>
    {
        var api = new AwsApiGateway.RestAPI("api", new()
        {
            Routes =
            {
                new AwsApiGateway.Inputs.RouteArgs
                {
                    Path = "/",
                    Target = new AwsApiGateway.Inputs.TargetArgs()
                    {
                        Type = AwsApiGateway.IntegrationType.Http_proxy,
                        Uri = "https://www.example.com/",
                    },
                },
            },
        });
    
        return new Dictionary<string, object?>
        {
            ["url"] = api.Url,
        };
    });
    
    package myproject;
    
    import com.pulumi.Pulumi;
    import com.pulumi.awsapigateway.enums.IntegrationType;
    import com.pulumi.awsapigateway.enums.Method;
    import com.pulumi.awsapigateway.RestAPI;
    import com.pulumi.awsapigateway.RestAPIArgs;
    import com.pulumi.awsapigateway.inputs.RouteArgs;
    import com.pulumi.awsapigateway.inputs.TargetArgs;
    
    public class App {
        public static void main(String[] args) {
            Pulumi.run(ctx -> {
    
                var api = new RestAPI("api", RestAPIArgs.builder()
                    .routes(new RouteArgs[]{
                        RouteArgs.builder()
                            .path("/")
                            .method(Method.GET)
                            .target(TargetArgs.builder()
                                .type(IntegrationType.Http_proxy)
                                .uri("https://www.example.com/")
                                .build()
                            )
                            .build(),
                    })
                    .build());
    
                ctx.export("url", api.url());
            });
        }
    }
    
    name: awsx-apigateway-http-proxy-yaml
    runtime: yaml
    description: An example that creates an API Gateway instance and configures a route as an HTTP proxy.
    
    resources:
      api:
        type: aws-apigateway:RestAPI
        properties:
          routes:
            - path: /
              method: GET
              target:
                type: http_proxy
                uri: https://www.example.com/
    
    outputs:
      url: ${api.url}
    

    Controlling Access to APIs

    AWS API Gateway supports several mechanisms for controlling and managing access to your APIs, including authentication and authorization with resource policies, standard AWS IAM roles and policies, Cognito user pools, and Lambda authorizers. You can also configure access in other ways, such as cross-origin resource sharing (CORS), client-side SSL certificates, Amazon Web Application Firewall (WAF), and limiting access to authorized clients through usage plans and API keys.

    The API Gateway component’s RestAPI resource supports three methods of controlling access to your APIs:

    • Amazon Cognito user pools let you create customizable authentication and authorization for your APIs.

    • Lambda authorizers are Lambda functions that control access to your APIs based on HTTP information available in headers, paths, query strings, or other request information, including bearer tokens.

    • Usage plans let you provide API keys to customers, and then track and limit usage of your APIs.

    Details on each are below. For those not directly supported, all of these capabilities are accessible to you in the Pulumi AWS package, and are described in depth in the article Controlling and Managing Access to a REST API in API Gateway.

    Cognito Authorizers

    Cognito Authorizers allow you to use Amazon Cognito User Pools as an authorizer for API Gateway. With a user pool, your users can sign into your web or mobile app through Amazon Cognito directly, social identity providers like Facebook, or SAML identity providers like Google. This enables your API Gateway to offload the difficult work of security to Cognito entirely.

    To require users to sign in through Cognito, you must specify the source of the authorization token (normally the Authorization header) and the ARN of the Cognito User Pool:

    "use strict";
    const aws = require("@pulumi/aws");
    const apigateway = require("@pulumi/aws-apigateway");
    
    const userPool = new aws.cognito.UserPool("user-pool");
    
    const api = new apigateway.RestAPI("api", {
        routes: [
            {
                path: "/",
                localPath: "www",
                authorizers: [
                    {
                        parameterName: "Authorization",
                        identitySource: ["method.request.header.Authorization"],
                        providerARNs: [userPool.arn],
                    },
                ],
            },
        ],
    });
    
    exports.url = api.url;
    
    import * as aws from "@pulumi/aws";
    import * as apigateway from "@pulumi/aws-apigateway";
    
    const userPool = new aws.cognito.UserPool("user-pool");
    
    const api = new apigateway.RestAPI("api", {
        routes: [
            {
                path: "/",
                localPath: "www",
                authorizers: [
                    {
                        parameterName: "Authorization",
                        identitySource: ["method.request.header.Authorization"],
                        providerARNs: [userPool.arn],
                    },
                ],
            },
        ],
    });
    
    export const url = api.url;
    
    import pulumi
    import pulumi_aws as aws
    import pulumi_aws_apigateway as apigateway
    
    user_pool = aws.cognito.UserPool("user-pool")
    
    api = apigateway.RestAPI(
        "api",
        routes=[
            apigateway.RouteArgs(
                path="/",
                method=apigateway.Method.GET,
                local_path="www",
                authorizers=apigateway.AuthorizerArgs(
                    parameter_name="Authorization",
                    identity_source=["method.request.header.Authorization"],
                    provider_arns=[user_pool.arn],
                ),
            )
        ],
    )
    
    pulumi.export("url", api.url)
    
    package main
    
    import (
    	"github.com/pulumi/pulumi-aws-apigateway/sdk/v2/go/apigateway"
    	"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/cognito"
    	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
    )
    
    func main() {
    	pulumi.Run(func(ctx *pulumi.Context) error {
    
    		userPool, err := cognito.NewUserPool(ctx, "user-pool", nil)
    		if err != nil {
    			return err
    		}
    
    		api, err := apigateway.NewRestAPI(ctx, "api", &apigateway.RestAPIArgs{
    			Routes: []apigateway.RouteArgs{
    				{
    					Path:      "/",
    					LocalPath: pulumi.StringRef("www"),
    					Authorizers: []apigateway.AuthorizerArgs{
    						{
    							ParameterName:  "Authorization",
    							IdentitySource: []string{"method.request.header.Authorization"},
    							ProviderARNs: []pulumi.StringInput{
    								userPool.Arn,
    							},
    						},
    					},
    				},
    			},
    		})
    		if err != nil {
    			return err
    		}
    
    		ctx.Export("url", api.Url)
    		return nil
    	})
    }
    
    using System.Collections.Generic;
    using Pulumi;
    using Aws = Pulumi.Aws;
    using AwsApiGateway = Pulumi.AwsApiGateway;
    
    return await Deployment.RunAsync(() =>
    {
        var userPool = new Aws.Cognito.UserPool("user-pool");
    
        var api = new AwsApiGateway.RestAPI(
            "api",
            new()
            {
                Routes =
                {
                    new AwsApiGateway.Inputs.RouteArgs
                    {
                        Path = "/",
                        Method = AwsApiGateway.Method.GET,
                        LocalPath = "www",
                        Authorizers =
                        {
                            new AwsApiGateway.Inputs.AuthorizerArgs
                            {
                                ParameterName = "Authorization",
                                IdentitySource = { "method.request.header.Authorization" },
                                ProviderARNs = { userPool.Arn },
                            },
                        },
                    },
                },
            }
        );
    
        return new Dictionary<string, object?> { ["url"] = api.Url };
    });
    
    package myproject;
    
    import java.util.List;
    
    import com.pulumi.Pulumi;
    import com.pulumi.aws.cognito.UserPool;
    import com.pulumi.awsapigateway.enums.Method;
    import com.pulumi.awsapigateway.RestAPI;
    import com.pulumi.awsapigateway.RestAPIArgs;
    import com.pulumi.awsapigateway.inputs.AuthorizerArgs;
    import com.pulumi.awsapigateway.inputs.RouteArgs;
    import com.pulumi.core.Output;
    
    public class App {
        public static void main(String[] args) {
            Pulumi.run(ctx -> {
    
                var userPool = new UserPool("user-pool");
    
                var api = new RestAPI("api", RestAPIArgs.builder()
                    .routes(new RouteArgs[]{
                        RouteArgs.builder()
                            .path("/")
                            .method(Method.GET)
                            .localPath("www")
                            .authorizers(new AuthorizerArgs[]{
                                AuthorizerArgs.builder()
                                    .parameterName("Authorization")
                                    .identitySource(List.of("method.request.header.Authorization"))
                                    .providerARNs(List.of(userPool.arn()))
                                    .build(),
                            })
                            .build(),
                    })
                    .build());
    
                ctx.export("url", api.url());
            });
        }
    }
    
    name: awsx-apigateway-auth-cognito-yaml
    runtime: yaml
    description: An example that deploys an API Gateway REST API with an Amazon Cognito authorizer.
    
    resources:
      userPool:
        type: aws:cognito:UserPool
    
      api:
        type: aws-apigateway:RestAPI
        properties:
          routes:
            - path: /
              localPath: www
              authorizers:
                - parameterName: Authorization
                  identitySource:
                    - method.request.header.Authorization
                  providerARNs:
                    - ${userPool.arn}
    
    outputs:
      url: ${api.url}
    

    When deployed, this configuration will require that a user authenticate, obtain an identity/access token, and call your API with said token.

    Lambda Authorizers

    Lambda Authorizers are AWS Lambda Functions that control access to an API. This allows you to use information in the request itself, including headers, paths, query parameters, or tokens, to decide whether a request is authorized to hit the backend.

    You can define a Lambda Authorizer for an event-handler route or a static route. API Gateway supports request or token type Lambda authorizers:

    • Request authorizers can use any part of the request parameters (e.g., headers, path parameters, or query parameters).

    • Token authorizers use an authorization token (i.e., a header of the form Authorization: token <token>)

    To define an Authorizer, you provide a Lambda that receives an authorizer event and responds with a valid authorizer response. See Pulumi Crosswalk for AWS Lambda for other ways you can define your Lambda for the Authorizer.

    Below is an example of a custom request authorizer. Because the authorizer has access to the content of the HTTP request, it can use any of the request’s properties to determine whether to grant access to the resource requested. For demonstration, this authorizer validates the request using a single, hard-coded token. (In practice, you’d more likely have the authorizer query a database or contact another service for this purpose.)

    "use strict";
    const aws = require("@pulumi/aws");
    const apigateway = require("@pulumi/aws-apigateway");
    
    const authorizer = new aws.lambda.CallbackFunction("authorizer", {
        callback: async (event, context) => {
            const effect = event.headers.Authorization === "token a-good-token" ? "Allow" : "Deny";
    
            return {
                principalId: "my-user",
                policyDocument: {
                    Version: "2012-10-17",
                    Statement: [
                        {
                            Action: "execute-api:Invoke",
                            Effect: effect,
                            Resource: event.methodArn,
                        },
                    ],
                },
            };
        },
    });
    
    const api = new apigateway.RestAPI("api", {
        routes: [
            {
                path: "/",
                method: "GET",
                localPath: "www",
                authorizers: [
                    {
                        authType: "custom",
                        parameterName: "Authorization",
                        type: "request",
                        identitySource: ["method.request.header.Authorization"],
                        handler: authorizer,
                    },
                ],
            },
        ],
    });
    
    exports.url = api.url;
    
    import * as aws from "@pulumi/aws";
    import * as apigateway from "@pulumi/aws-apigateway";
    
    const authorizer = new aws.lambda.CallbackFunction("authorizer", {
        callback: async (event: any, context) => {
            const effect = event.headers.Authorization === "token a-good-token" ? "Allow" : "Deny";
    
            return {
                principalId: "my-user",
                policyDocument: {
                    Version: "2012-10-17",
                    Statement: [
                        {
                            Action: "execute-api:Invoke",
                            Effect: effect,
                            Resource: event.methodArn,
                        },
                    ],
                },
            };
        },
    });
    
    const api = new apigateway.RestAPI("api", {
        routes: [
            {
                path: "/",
                method: "GET",
                localPath: "www",
                authorizers: [
                    {
                        authType: "custom",
                        parameterName: "Authorization",
                        type: "request",
                        identitySource: ["method.request.header.Authorization"],
                        handler: authorizer,
                    },
                ],
            },
        ],
    });
    
    export const url = api.url;
    
    import json
    import pulumi
    import pulumi_aws as aws
    import pulumi_aws_apigateway as apigateway
    
    role = aws.iam.Role(
        "role",
        assume_role_policy=json.dumps(
            {
                "Version": "2012-10-17",
                "Statement": [
                    {
                        "Action": "sts:AssumeRole",
                        "Effect": "Allow",
                        "Principal": {
                            "Service": "lambda.amazonaws.com",
                        },
                    }
                ],
            }
        ),
        managed_policy_arns=[aws.iam.ManagedPolicy.AWS_LAMBDA_BASIC_EXECUTION_ROLE],
    )
    
    authorizer = aws.lambda_.Function(
        "authorizer",
        runtime="python3.9",
        handler="handler.handler",
        role=role.arn,
        code=pulumi.FileArchive("./authorizer"),
    )
    
    api = apigateway.RestAPI(
        "api",
        routes=[
            apigateway.RouteArgs(
                path="/",
                method=apigateway.Method.GET,
                local_path="www",
                authorizers=[
                    apigateway.AuthorizerArgs(
                        auth_type="custom",
                        type="request",
                        parameter_name="Authorization",
                        identity_source=["method.request.header.Authorization"],
                        handler=authorizer,
                    ),
                ],
            ),
        ],
    )
    
    pulumi.export("url", api.url)
    
    package main
    
    import (
    	"encoding/json"
    
    	"github.com/pulumi/pulumi-aws-apigateway/sdk/v2/go/apigateway"
    	"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/iam"
    	"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/lambda"
    	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
    )
    
    func main() {
    	pulumi.Run(func(ctx *pulumi.Context) error {
    
    		policy, err := json.Marshal(map[string]interface{}{
    			"Version": "2012-10-17",
    			"Statement": []map[string]interface{}{
    				{
    					"Action": "sts:AssumeRole",
    					"Effect": "Allow",
    					"Principal": map[string]interface{}{
    						"Service": "lambda.amazonaws.com",
    					},
    				},
    			},
    		})
    		if err != nil {
    			return err
    		}
    
    		role, err := iam.NewRole(ctx, "role", &iam.RoleArgs{
    			AssumeRolePolicy: pulumi.String(policy),
    			ManagedPolicyArns: pulumi.StringArray{
    				iam.ManagedPolicyAWSLambdaBasicExecutionRole,
    			},
    		})
    		if err != nil {
    			return err
    		}
    
    		authorizer, err := lambda.NewFunction(ctx, "authorizer", &lambda.FunctionArgs{
    			Runtime: pulumi.String("python3.9"),
    			Handler: pulumi.String("handler.handler"),
    			Role:    role.Arn,
    			Code:    pulumi.NewFileArchive("./authorizer"),
    		})
    		if err != nil {
    			return err
    		}
    
    		methodGET := apigateway.MethodGET
    		api, err := apigateway.NewRestAPI(ctx, "api", &apigateway.RestAPIArgs{
    			Routes: []apigateway.RouteArgs{
    				{
    					Path:      "/",
    					Method:    &methodGET,
    					LocalPath: pulumi.StringRef("www"),
    					Authorizers: []apigateway.AuthorizerArgs{
    						{
    							AuthType:       pulumi.StringRef("custom"),
    							Type:           pulumi.StringRef("request"),
    							ParameterName:  "Authorization",
    							IdentitySource: []string{"method.request.header.Authorization"},
    							Handler:        authorizer,
    						},
    					},
    				},
    			},
    		})
    		if err != nil {
    			return err
    		}
    
    		ctx.Export("url", api.Url)
    		return nil
    	})
    }
    
    using System.Collections.Generic;
    using System.Text.Json;
    using Pulumi;
    using Aws = Pulumi.Aws;
    using AwsApiGateway = Pulumi.AwsApiGateway;
    
    return await Deployment.RunAsync(() =>
    {
        var role = new Aws.Iam.Role("role", new()
        {
            AssumeRolePolicy = JsonSerializer.Serialize(new Dictionary<string, object?>
            {
                ["Version"] = "2012-10-17",
                ["Statement"] = new[]
                {
                    new Dictionary<string, object?>
                    {
                        ["Action"] = "sts:AssumeRole",
                        ["Effect"] = "Allow",
                        ["Principal"] = new Dictionary<string, object?>
                        {
                            ["Service"] = "lambda.amazonaws.com",
                        },
                    },
                },
            }),
            ManagedPolicyArns = new[]
            {
                Aws.Iam.ManagedPolicy.AWSLambdaBasicExecutionRole.ToString(),
            },
        });
    
        var authorizer = new Aws.Lambda.Function("authorizer", new()
        {
            Runtime = "python3.9",
            Handler = "handler.handler",
            Role = role.Arn,
            Code = new FileArchive("./authorizer"),
        });
    
        var api = new AwsApiGateway.RestAPI(
            "api",
            new()
            {
                Routes =
                {
                    new AwsApiGateway.Inputs.RouteArgs
                    {
                        Path = "/",
                        Method = AwsApiGateway.Method.GET,
                        LocalPath = "www",
                        Authorizers =
                        {
                            new AwsApiGateway.Inputs.AuthorizerArgs
                            {
                                AuthType = "custom",
                                Type = "request",
                                ParameterName = "Authorization",
                                IdentitySource = { "method.request.header.Authorization" },
                                Handler = authorizer,
                            },
                        },
                    },
                },
            }
        );
    
        return new Dictionary<string, object?> { ["url"] = api.Url };
    });
    
    package myproject;
    
    import java.util.List;
    
    import com.pulumi.Pulumi;
    import com.pulumi.aws.iam.Role;
    import com.pulumi.aws.iam.RoleArgs;
    import com.pulumi.aws.iam.enums.ManagedPolicy;
    import com.pulumi.awsapigateway.enums.Method;
    import com.pulumi.aws.lambda.Function;
    import com.pulumi.aws.lambda.FunctionArgs;
    import com.pulumi.awsapigateway.RestAPI;
    import com.pulumi.awsapigateway.RestAPIArgs;
    import com.pulumi.awsapigateway.inputs.AuthorizerArgs;
    import com.pulumi.awsapigateway.inputs.RouteArgs;
    import static com.pulumi.codegen.internal.Serialization.*;
    
    public class App {
        public static void main(String[] args) {
            Pulumi.run(ctx -> {
    
                var role = new Role("role", RoleArgs.builder()
                    .assumeRolePolicy(serializeJson(
                        jsonObject(
                            jsonProperty("Version", "2012-10-17"),
                            jsonProperty("Statement", jsonArray(jsonObject(
                                jsonProperty("Action", "sts:AssumeRole"),
                                jsonProperty("Effect", "Allow"),
                                jsonProperty("Sid", ""),
                                jsonProperty("Principal", jsonObject(
                                    jsonProperty("Service", "lambda.amazonaws.com")
                                ))
                            )))
                        )))
                    .managedPolicyArns(List.of(ManagedPolicy.AWSLambdaBasicExecutionRole.getValue()))
                    .build());
    
                var authorizer = new Function("authorizer", FunctionArgs.builder()
                    .runtime("python3.9")
                    .handler("handler.handler")
                    .role(role.arn())
                    .code(new com.pulumi.asset.FileArchive("./authorizer"))
                    .build());
    
                var api = new RestAPI("api", RestAPIArgs.builder()
                    .routes(new RouteArgs[]{
                        RouteArgs.builder()
                            .path("/")
                            .method(Method.GET)
                            .localPath("www")
                            .authorizers(new AuthorizerArgs[]{
                                AuthorizerArgs.builder()
                                    .authType("custom")
                                    .type("request")
                                    .parameterName("Authorization")
                                    .identitySource(List.of("method.request.header.Authorization"))
                                    .handler(authorizer)
                                    .build(),
                            })
                            .build(),
                    })
                    .build());
    
                ctx.export("url", api.url());
            });
        }
    }
    
    name: awsx-apigateway-auth-lambda-yaml
    runtime: yaml
    description: An example that deploys an API Gateway REST API with an AWS Lambda authorizer.
    
    resources:
      role:
        type: aws:iam:Role
        properties:
          assumeRolePolicy:
            fn::toJSON:
              Version: "2012-10-17"
              Statement:
                - Action: sts:AssumeRole
                  Effect: Allow
                  Principal:
                    Service: lambda.amazonaws.com
          managedPolicyArns:
            - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
    
      authorizer:
        type: aws:lambda:Function
        properties:
          runtime: python3.9
          handler: handler.handler
          role: ${role.arn}
          code:
            fn::fileArchive: ./authorizer
    
      api:
        type: aws-apigateway:RestAPI
        properties:
          routes:
            - path: /
              localPath: www
              authorizers:
                - authType: custom
                  type: request
                  parameterName: Authorization
                  identitySource:
                    - method.request.header.Authorization
                  handler: ${authorizer}
    
    outputs:
      url: ${api.url}
    

    Once deployed, the protected route only accepts requests containing the token in the Authorization header:

    $ curl -H "Authorization: token a-good-token" $(pulumi stack output url)
    <html>
        <body>
            <p>Hello from API Gateway + S3!</p>
        </body>
    </html>
    
    $ curl $(pulumi stack output url)
    {"message":"Unauthorized"}
    

    For additional information about API Gateway Lambda Authorizers, see the AWS documentation.

    Request Validation

    API Gateway can perform basic validations against the parameters of a request, the request payload, or both. When a validation fails, a 400 error is returned immediately, without invoking the backend integration, and the validation results are published to CloudWatch Logs, eliminating unnecessary calls to the backend.

    For basic validation, API Gateway can verify either or both of these conditions:

    • The request parameters of an incoming request (headers, query parameters, and path parameters) are included and non-blank.

    • The request payload adheres to the configured JSON schema request model of the method.

    When enabling validation, you choose a validation scope and validation rules.

    Assigning Validators to APIs and Methods

    Validators can be assigned for an entire API or at the individual method level, such as only for POST requests on a given route. The validators defined at a method level override any validator set at the global (i.e., API Gateway instance) level.

    To enable validation, pass the requestValidator property either on the RestAPI resource itself or one or more of its individual routes. The following validator values are supported:

    • ALL: Validates both the request body and request parameters.
    • BODY_ONLY: Validates only the request body.
    • PARAMS_ONLY: Validates only the request parameters.

    The following example enables parameter validation on all routes, and both parameter and body validation on a specific route:

    "use strict";
    const apigateway = require("@pulumi/aws-apigateway");
    
    const api = new apigateway.RestAPI("api", {
        requestValidator: apigateway.RequestValidator.PARAMS_ONLY,
        routes: [
            {
                path: "/search",
                method: apigateway.Method.GET,
                target: {
                    type: "http_proxy",
                    uri: "https://www.example.com/",
                },
                requestValidator: apigateway.RequestValidator.ALL,
                requiredParameters: [
                    {
                        name: "q",
                        in: "query",
                    },
                ],
            },
        ],
    });
    
    exports.url = api.url;
    
    import * as apigateway from "@pulumi/aws-apigateway";
    
    const api = new apigateway.RestAPI("api", {
        requestValidator: apigateway.RequestValidator.PARAMS_ONLY,
        routes: [
            {
                path: "/search",
                method: apigateway.Method.GET,
                target: {
                    type: "http_proxy",
                    uri: "https://www.example.com/",
                },
                requestValidator: apigateway.RequestValidator.ALL,
                requiredParameters: [
                    {
                        name: "q",
                        in: "query",
                    },
                ],
            },
        ],
    });
    
    export const url = api.url;
    
    import pulumi
    import pulumi_aws_apigateway as apigateway
    
    api = apigateway.RestAPI(
        "api",
        apigateway.RestAPIArgs(
            request_validator=apigateway.RequestValidator.PARAM_S_ONLY,
            routes=[
                apigateway.RouteArgs(
                    path="/search",
                    method=apigateway.Method.GET,
                    target=apigateway.TargetArgs(
                        type="http_proxy",
                        uri="https://www.example.com/",
                    ),
                    request_validator=apigateway.RequestValidator.ALL,
                    required_parameters=[
                        apigateway.RequiredParameterArgs(
                            name="q",
                            in_="query",
                        ),
                    ],
                ),
            ],
        )
    
    )
    
    pulumi.export("url", api.url)
    
    package main
    
    import (
    	"github.com/pulumi/pulumi-aws-apigateway/sdk/v2/go/apigateway"
    	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
    )
    
    func main() {
    	pulumi.Run(func(ctx *pulumi.Context) error {
    
    		GET := apigateway.MethodGET
    		ALL := apigateway.RequestValidatorALL
    		PARAMS_ONLY := apigateway.RequestValidator_PARAMS_ONLY
    
    		api, err := apigateway.NewRestAPI(ctx, "api", &apigateway.RestAPIArgs{
    			RequestValidator: &PARAMS_ONLY,
    
    			Routes: []apigateway.RouteArgs{
    				{
    					Path:   "/search",
    					Method: &GET,
    					Target: &apigateway.TargetArgs{
    						Type: apigateway.IntegrationType_Http_proxy,
    						Uri:  pulumi.String("https://www.example.com/"),
    					},
    					RequestValidator: &ALL,
    					RequiredParameters: []apigateway.RequiredParameterArgs{
    						{
    							Name: pulumi.StringPtr("q"),
    							In:   pulumi.StringPtr("query"),
    						},
    					},
    				},
    			},
    		})
    		if err != nil {
    			return err
    		}
    
    		ctx.Export("url", api.Url)
    		return nil
    	})
    }
    
    using System.Collections.Generic;
    using Pulumi;
    using Pulumi.AwsApiGateway.Inputs;
    using AwsApiGateway = Pulumi.AwsApiGateway;
    
    return await Deployment.RunAsync(() =>
    {
        var api = new AwsApiGateway.RestAPI("api", new()
        {
            RequestValidator = AwsApiGateway.RequestValidator.PARAMS_ONLY,
    
            Routes = {
                new RouteArgs()
                {
                    Path = "/search",
                    Method = AwsApiGateway.Method.GET,
                    Target = new TargetArgs()
                    {
                        Type = AwsApiGateway.IntegrationType.Http_proxy,
                        Uri = "https://www.example.com/",
                    },
                    RequestValidator = AwsApiGateway.RequestValidator.ALL,
                    RequiredParameters = {
                        new RequiredParameterArgs() {
                            Name = "q",
                            In = "query",
                        },
                    },
                },
            },
        });
    
        return new Dictionary<string, object?>
        {
            ["url"] = api.Url,
        };
    });
    
    package myproject;
    
    import java.util.List;
    
    import com.pulumi.Pulumi;
    import com.pulumi.awsapigateway.enums.IntegrationType;
    import com.pulumi.awsapigateway.enums.Method;
    import com.pulumi.awsapigateway.enums.RequestValidator;
    import com.pulumi.awsapigateway.RestAPI;
    import com.pulumi.awsapigateway.RestAPIArgs;
    import com.pulumi.awsapigateway.inputs.RequiredParameterArgs;
    import com.pulumi.awsapigateway.inputs.RouteArgs;
    import com.pulumi.awsapigateway.inputs.TargetArgs;
    
    public class App {
        public static void main(String[] args) {
            Pulumi.run(ctx -> {
    
                var api = new RestAPI("api", RestAPIArgs.builder()
                    .requestValidator(RequestValidator.PARAMS_ONLY)
                    .routes(new RouteArgs[]{
                        RouteArgs.builder()
                            .path("/search")
                            .method(Method.GET)
                            .target(TargetArgs.builder()
                                .type(IntegrationType.Http_proxy)
                                .uri("https://www.example.com/")
                                .build()
                            )
                            .requestValidator(RequestValidator.ALL)
                            .requiredParameters(List.of(RequiredParameterArgs.builder()
                                .name("q")
                                .in("query")
                                .build()))
                            .build(),
                    })
                    .build());
    
                ctx.export("url", api.url());
            });
        }
    }
    
    name: awsx-apigateway-validation-types-yaml
    runtime: yaml
    description: An example of configuring request validators for an API Gateway instance.
    
    resources:
      api:
        type: aws-apigateway:RestAPI
        properties:
          requestValidator: PARAMS_ONLY
          routes:
            - path: /search
              method: GET
              target:
                type: http_proxy
                uri: https://www.example.com/
              requestValidator: ALL
              requiredParameters:
                - name: q
                  in: query
    
    outputs:
      url: ${api.url}
    

    Request Parameter Validation

    To validate that a particular parameter is present in each request, use the requiredParams route property. This property is an array that defines each required parameter and where the parameter is expected to be found (header, path, query), using the name and in properties, respectively.

    The following program uses request validation to ensure that the q parameter is present and non-empty on all /search requests:

    "use strict";
    const apigateway = require("@pulumi/aws-apigateway");
    
    const api = new apigateway.RestAPI("api", {
        requestValidator: apigateway.RequestValidator.PARAMS_ONLY,
        routes: [
            {
                path: "/search",
                method: apigateway.Method.GET,
                target: {
                    type: "http_proxy",
                    uri: "https://www.example.com/",
                },
                requestValidator: apigateway.RequestValidator.ALL,
                requiredParameters: [
                    {
                        name: "q",
                        in: "query",
                    },
                ],
            },
        ],
    });
    
    exports.url = api.url;
    
    import * as apigateway from "@pulumi/aws-apigateway";
    
    const api = new apigateway.RestAPI("api", {
        requestValidator: apigateway.RequestValidator.PARAMS_ONLY,
        routes: [
            {
                path: "/search",
                method: apigateway.Method.GET,
                target: {
                    type: "http_proxy",
                    uri: "https://www.example.com/",
                },
                requestValidator: apigateway.RequestValidator.ALL,
                requiredParameters: [
                    {
                        name: "q",
                        in: "query",
                    },
                ],
            },
        ],
    });
    
    export const url = api.url;
    
    import pulumi
    import pulumi_aws_apigateway as apigateway
    
    api = apigateway.RestAPI(
        "api",
        apigateway.RestAPIArgs(
            request_validator=apigateway.RequestValidator.PARAM_S_ONLY,
            routes=[
                apigateway.RouteArgs(
                    path="/search",
                    method=apigateway.Method.GET,
                    target=apigateway.TargetArgs(
                        type="http_proxy",
                        uri="https://www.example.com/",
                    ),
                    request_validator=apigateway.RequestValidator.ALL,
                    required_parameters=[
                        apigateway.RequiredParameterArgs(
                            name="q",
                            in_="query",
                        ),
                    ],
                ),
            ],
        )
    
    )
    
    pulumi.export("url", api.url)
    
    package main
    
    import (
    	"github.com/pulumi/pulumi-aws-apigateway/sdk/v2/go/apigateway"
    	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
    )
    
    func main() {
    	pulumi.Run(func(ctx *pulumi.Context) error {
    
    		GET := apigateway.MethodGET
    		ALL := apigateway.RequestValidatorALL
    		PARAMS_ONLY := apigateway.RequestValidator_PARAMS_ONLY
    
    		api, err := apigateway.NewRestAPI(ctx, "api", &apigateway.RestAPIArgs{
    			RequestValidator: &PARAMS_ONLY,
    
    			Routes: []apigateway.RouteArgs{
    				{
    					Path:   "/search",
    					Method: &GET,
    					Target: &apigateway.TargetArgs{
    						Type: apigateway.IntegrationType_Http_proxy,
    						Uri:  pulumi.String("https://www.example.com/"),
    					},
    					RequestValidator: &ALL,
    					RequiredParameters: []apigateway.RequiredParameterArgs{
    						{
    							Name: pulumi.StringPtr("q"),
    							In:   pulumi.StringPtr("query"),
    						},
    					},
    				},
    			},
    		})
    		if err != nil {
    			return err
    		}
    
    		ctx.Export("url", api.Url)
    		return nil
    	})
    }
    
    using System.Collections.Generic;
    using Pulumi;
    using Pulumi.AwsApiGateway.Inputs;
    using AwsApiGateway = Pulumi.AwsApiGateway;
    
    return await Deployment.RunAsync(() =>
    {
        var api = new AwsApiGateway.RestAPI("api", new()
        {
            RequestValidator = AwsApiGateway.RequestValidator.PARAMS_ONLY,
    
            Routes = {
                new RouteArgs()
                {
                    Path = "/search",
                    Method = AwsApiGateway.Method.GET,
                    Target = new TargetArgs()
                    {
                        Type = AwsApiGateway.IntegrationType.Http_proxy,
                        Uri = "https://www.example.com/",
                    },
                    RequestValidator = AwsApiGateway.RequestValidator.ALL,
                    RequiredParameters = {
                        new RequiredParameterArgs() {
                            Name = "q",
                            In = "query",
                        },
                    },
                },
            },
        });
    
        return new Dictionary<string, object?>
        {
            ["url"] = api.Url,
        };
    });
    
    package myproject;
    
    import java.util.List;
    
    import com.pulumi.Pulumi;
    import com.pulumi.awsapigateway.enums.IntegrationType;
    import com.pulumi.awsapigateway.enums.Method;
    import com.pulumi.awsapigateway.enums.RequestValidator;
    import com.pulumi.awsapigateway.RestAPI;
    import com.pulumi.awsapigateway.RestAPIArgs;
    import com.pulumi.awsapigateway.inputs.RequiredParameterArgs;
    import com.pulumi.awsapigateway.inputs.RouteArgs;
    import com.pulumi.awsapigateway.inputs.TargetArgs;
    
    public class App {
        public static void main(String[] args) {
            Pulumi.run(ctx -> {
    
                var api = new RestAPI("api", RestAPIArgs.builder()
                    .requestValidator(RequestValidator.PARAMS_ONLY)
                    .routes(new RouteArgs[]{
                        RouteArgs.builder()
                            .path("/search")
                            .method(Method.GET)
                            .target(TargetArgs.builder()
                                .type(IntegrationType.Http_proxy)
                                .uri("https://www.example.com/")
                                .build()
                            )
                            .requestValidator(RequestValidator.ALL)
                            .requiredParameters(List.of(RequiredParameterArgs.builder()
                                .name("q")
                                .in("query")
                                .build()))
                            .build(),
                    })
                    .build());
    
                ctx.export("url", api.url());
            });
        }
    }
    
    name: awsx-apigateway-validation-types-yaml
    runtime: yaml
    description: An example of configuring request validators for an API Gateway instance.
    
    resources:
      api:
        type: aws-apigateway:RestAPI
        properties:
          requestValidator: PARAMS_ONLY
          routes:
            - path: /search
              method: GET
              target:
                type: http_proxy
                uri: https://www.example.com/
              requestValidator: ALL
              requiredParameters:
                - name: q
                  in: query
    
    outputs:
      url: ${api.url}
    

    For more information about request validation, see Use Request Validation in API Gateway in the AWS documentation.

    Request body validation is not yet supported. If you have a need for it, we would love to hear from you. Comment on this open issue with details about your use case.

    Use API Keys to Limit Requests

    After you create, test, and deploy your APIs, you can use Amazon API Gateway usage plans to make them available to your customers. Usage plans and API keys allow customers to use your API at agreed-upon request rates and quotas that meet their business requirements and budget constraints. If desired, you can set API-level throttling limits.

    To require an API key for a given route, set the route’s apiKeyRequired property to true, and at the API level, specify whether the key should be provided in a HEADER (specifically the x-api-key header) or AUTHORIZER (in which case a Lambda authorizer sends the API key as part of the authorization response). If unspecified, the default API key source is HEADER.

    Setting up API key-based authorization in API Gateway involves three steps:

    1. Creating the API key itself — for example, with an ApiKey resource
    2. Defining a usage plan for the API (which can optionally define quotas and throttling rules)
    3. Associating the key and usage plan with the API Gateway instance

    In the following example, an ApiKey resource and UsagePlan are provisioned and associated with a RestAPI instance, and the generated API key value is exported as a Pulumi stack output (and tracked as an encrypted secret):

    "use strict";
    const aws = require("@pulumi/aws");
    const apigateway = require("@pulumi/aws-apigateway");
    
    const api = new apigateway.RestAPI("api", {
        apiKeySource: "HEADER",
        routes: [
            {
                path: "/",
                localPath: "data",
                contentType: "application/json",
                index: "index.json",
                apiKeyRequired: true,
            },
        ],
    });
    
    const key = new aws.apigateway.ApiKey("key");
    
    const plan = new aws.apigateway.UsagePlan("plan", {
        apiStages: [
            {
                apiId: api.api.id,
                stage: api.stage.stageName,
            },
        ],
    });
    
    const planKey = new aws.apigateway.UsagePlanKey("plan-key", {
        keyId: key.id,
        keyType: "API_KEY",
        usagePlanId: plan.id,
    });
    
    exports.url = api.url;
    exports.apiKey = key.value;
    
    import * as aws from "@pulumi/aws";
    import * as apigateway from "@pulumi/aws-apigateway";
    
    const api = new apigateway.RestAPI("api", {
        apiKeySource: "HEADER",
        routes: [
            {
                path: "/",
                localPath: "data",
                contentType: "application/json",
                index: "index.json",
                apiKeyRequired: true,
            },
        ],
    });
    
    const key = new aws.apigateway.ApiKey("key");
    
    const plan = new aws.apigateway.UsagePlan("plan", {
        apiStages: [
            {
                apiId: api.api.id,
                stage: api.stage.stageName,
            },
        ],
    });
    
    const planKey = new aws.apigateway.UsagePlanKey("plan-key", {
        keyId: key.id,
        keyType: "API_KEY",
        usagePlanId: plan.id,
    });
    
    export const url = api.url;
    export const apiKey = key.value;
    
    import pulumi
    import pulumi_aws as aws
    import pulumi_aws_apigateway as apigateway
    
    api = apigateway.RestAPI(
        "api",
        apigateway.RestAPIArgs(
            api_key_source=apigateway.APIKeySource.HEADER,
            routes=[
                apigateway.RouteArgs(
                    path="/",
                    method=apigateway.Method.GET,
                    local_path="data",
                    index="index.json",
                    content_type="application/json",
                    api_key_required=True,
                ),
            ],
        )
    )
    
    key = aws.apigateway.ApiKey("key")
    
    plan = aws.apigateway.UsagePlan("plan", aws.apigateway.UsagePlanArgs(
        api_stages=[
            aws.apigateway.UsagePlanApiStageArgs(
                api_id=api.api.id,
                stage=api.stage.stage_name,
            ),
        ],
    ))
    
    plan_key = aws.apigateway.UsagePlanKey("plan-key", aws.apigateway.UsagePlanKeyArgs(
        key_id=key.id,
        key_type="API_KEY",
        usage_plan_id=plan.id,
    ))
    
    pulumi.export("url", api.url)
    pulumi.export("apiKey", key.value)
    
    package main
    
    import (
    	"github.com/pulumi/pulumi-aws-apigateway/sdk/v2/go/apigateway"
    	awsapigateway "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/apigateway"
    	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
    )
    
    func main() {
    	pulumi.Run(func(ctx *pulumi.Context) error {
    
    		HEADER := apigateway.APIKeySourceHEADER
    		api, err := apigateway.NewRestAPI(ctx, "api", &apigateway.RestAPIArgs{
    			ApiKeySource: &HEADER,
    			Routes: []apigateway.RouteArgs{
    				{
    					Path:           "/",
    					LocalPath:      pulumi.StringRef("data"),
    					Index:          pulumi.String("index.json"),
    					ContentType:    pulumi.StringRef("application/json"),
    					ApiKeyRequired: pulumi.BoolRef(true),
    				},
    			},
    		})
    		if err != nil {
    			return err
    		}
    
    		key, err := awsapigateway.NewApiKey(ctx, "key", nil)
    		if err != nil {
    			return err
    		}
    
    		apiID := api.Api.ApplyT(func(api *awsapigateway.RestApi) pulumi.StringOutput {
    			return api.ID().ToStringOutput()
    		}).ApplyT(func(id interface{}) string {
    			return id.(string)
    		}).(pulumi.StringOutput)
    
    		plan, err := awsapigateway.NewUsagePlan(ctx, "plan", &awsapigateway.UsagePlanArgs{
    			ApiStages: awsapigateway.UsagePlanApiStageArray{
    				&awsapigateway.UsagePlanApiStageArgs{
    					ApiId: apiID,
    					Stage: api.Stage.StageName(),
    				},
    			},
    		})
    		if err != nil {
    			return err
    		}
    
    		_, err = awsapigateway.NewUsagePlanKey(ctx, "plan-key", &awsapigateway.UsagePlanKeyArgs{
    			KeyId:       key.ID(),
    			KeyType:     pulumi.String("API_KEY"),
    			UsagePlanId: plan.ID(),
    		})
    		if err != nil {
    			return err
    		}
    
    		ctx.Export("url", api.Url)
    		ctx.Export("apiKey", key.Value)
    		return nil
    	})
    }
    
    using System.Collections.Generic;
    using Pulumi;
    using Aws = Pulumi.Aws;
    using AwsApiGateway = Pulumi.AwsApiGateway;
    using Pulumi.AwsApiGateway.Inputs;
    
    return await Deployment.RunAsync(() =>
    {
        var api = new AwsApiGateway.RestAPI("api", new()
        {
            ApiKeySource = AwsApiGateway.APIKeySource.HEADER,
            Routes =
            {
                new RouteArgs()
                {
                    Path = "/",
                    LocalPath = "data",
                    Index = "index.json",
                    ContentType = "application/json",
                    ApiKeyRequired = true,
                },
            },
        });
    
        var key = new Aws.ApiGateway.ApiKey("key");
    
        var plan = new Aws.ApiGateway.UsagePlan("plan", new()
        {
            ApiStages = {
                new Aws.ApiGateway.Inputs.UsagePlanApiStageArgs()
                {
                    ApiId = api.Api.Apply(api => api.Id),
                    Stage = api.Stage.Apply(stage => stage.StageName),
                },
            },
        });
    
        var planKey = new Aws.ApiGateway.UsagePlanKey("plan-key", new()
        {
            KeyId = key.Id,
            KeyType = "API_KEY",
            UsagePlanId = plan.Id,
        });
    
        return new Dictionary<string, object?>
        {
            ["url"] = api.Url,
            ["apiKey"] = key.Value,
        };
    });
    
    package myproject;
    
    import java.util.List;
    
    import com.pulumi.Pulumi;
    import com.pulumi.aws.apigateway.ApiKey;
    import com.pulumi.aws.apigateway.UsagePlan;
    import com.pulumi.aws.apigateway.UsagePlanArgs;
    import com.pulumi.aws.apigateway.UsagePlanKey;
    import com.pulumi.aws.apigateway.UsagePlanKeyArgs;
    import com.pulumi.aws.apigateway.inputs.UsagePlanApiStageArgs;
    import com.pulumi.awsapigateway.enums.APIKeySource;
    import com.pulumi.awsapigateway.enums.Method;
    import com.pulumi.awsapigateway.RestAPI;
    import com.pulumi.awsapigateway.RestAPIArgs;
    import com.pulumi.awsapigateway.inputs.RouteArgs;
    
    public class App {
        public static void main(String[] args) {
            Pulumi.run(ctx -> {
    
                var api = new RestAPI("api", RestAPIArgs.builder()
                    .apiKeySource(APIKeySource.HEADER)
                    .routes(new RouteArgs[]{
                        RouteArgs.builder()
                            .path("/")
                            .method(Method.GET)
                            .localPath("data")
                            .index(("index.json"))
                            .contentType("application/json")
                            .apiKeyRequired(true)
                            .build(),
                    })
                    .build());
    
                var key = new ApiKey("key");
    
                var plan = new UsagePlan("plan", UsagePlanArgs.builder()
                    .apiStages(List.of(UsagePlanApiStageArgs.builder()
                        .apiId(api.api().apply(a -> a.id()))
                        .stage(api.stage().apply(s -> s.stageName()))
                        .build()))
                    .build());
    
                var planKey = new UsagePlanKey("plan-key", UsagePlanKeyArgs.builder()
                    .keyId(key.id())
                    .keyType("API_KEY")
                    .usagePlanId(plan.id())
                    .build());
    
                ctx.export("url", api.url());
                ctx.export("apiKey", key.value());
            });
        }
    }
    
    name: awsx-apigateway-api-keys-yaml
    runtime: yaml
    description: An example that deploys an API Gateway instance with support for API keys.
    
    resources:
      api:
        type: aws-apigateway:RestAPI
        properties:
          routes:
            - path: /
              localPath: data
              index: index.json
              contentType: application/json
              apiKeyRequired: true
    
      key:
        type: aws:apigateway:ApiKey
    
      plan:
        type: aws:apigateway:UsagePlan
        properties:
          apiStages:
            - apiId: ${api.api.id}
              stage: ${api.stage.stageName}
    
      planKey:
        type: aws:apigateway:UsagePlanKey
        properties:
          keyId: ${key.id}
          keyType: "API_KEY"
          usagePlanId: ${plan.id}
    
    outputs:
      url: ${api.url}
      apiKey: ${key.value}
    

    Note that when using the HEADER API key source, requests are expected to provide the token in a header named x-api-key:

    $ curl -H "x-api-key: $(pulumi stack output apiKey --show-secrets)" $(pulumi stack output url)
    {
        "message": "Hello from API Gateway!"
    }
    
    $ curl $(pulumi stack output url)
    {"message":"Unauthorized"}
    

    For more information about Usage Plans and API Keys, refer to Create and Use Usage Plans with API Keys.

    Custom Domains and SSL

    API Gateway automatically provisions and assigns a domain name, URL that contains the stage, and SSL support. Generated URLs look something like https://no90ji5v23.execute-api.us-west-2.amazonaws.com/stage/, where the host portion of the URL refers to an API endpoint that can be edge-optimized or regional.

    Although it’s great to have a URL with SSL support that works immediately, the resulting URL isn’t user-friendly or very easy to remember, and may not be suitable for business scenarios that require using company domains.

    To provide a simpler and more intuitive URL for your API users, you can configure a custom domain name for your API Gateway instance (such as api.example.com) and customize the base path of the URL to be something other than /stage. When you configure a custom domain, API Gateway also sets up an edge-optimized Amazon CloudFront Content Distribution Network (CDN) for you.

    The following example shows how to configure an API Gateway instance with a custom domain using Route53 and a free SSL certificate from AWS Certificate Manager (ACM). (ACM also supports importing certificates issued by third-party certificate authorities.) Note that the ACM certificate is created in the us-east-1 region (a CloudFront requirement) and validated with a CertificateValidation resource that verifies domain ownership through Route53 DNS.

    const aws = require("@pulumi/aws");
    const pulumi = require("@pulumi/pulumi");
    const apigateway = require("@pulumi/aws-apigateway");
    
    const hostedZoneName = "example.com";
    const domainName = `myapp.${hostedZoneName}`;
    
    // Look up your existing Route 53 hosted zone.
    const zone = aws.route53.getZoneOutput({ name: hostedZoneName });
    
    const usEast1 = new aws.Provider("us-east-1", {
        region: "us-east-1",
    });
    
    // Provision a new ACM certificate.
    const certificate = new aws.acm.Certificate(
        "certificate",
        {
            domainName: domainName,
            validationMethod: "DNS",
        },
        { provider: usEast1 },
    );
    
    // Validate the ACM certificate with DNS.
    const validationOption = certificate.domainValidationOptions[0];
    const validationRecord = new aws.route53.Record("certificate-validation-record", {
        name: validationOption.resourceRecordName,
        type: validationOption.resourceRecordType,
        records: [validationOption.resourceRecordValue],
        zoneId: zone.zoneId,
        ttl: 60,
    });
    
    const validation = new aws.acm.CertificateValidation(
        "certificate-validation",
        {
            certificateArn: certificate.arn,
            validationRecordFqdns: [validationRecord.fqdn],
        },
        { provider: usEast1 },
    );
    
    const api = new apigateway.RestAPI("api", {
        routes: [
            {
                path: "/",
                localPath: "www",
            },
        ],
    });
    
    const gatewayDomainName = new aws.apigateway.DomainName(
        "gateway-domain-name",
        {
            certificateArn: certificate.arn,
            domainName,
        },
        { dependsOn: validation },
    );
    
    const gatewayDNSRecord = new aws.route53.Record("gateway-dns-record", {
        zoneId: zone.zoneId,
        type: "A",
        name: domainName,
        aliases: [
            {
                name: gatewayDomainName.cloudfrontDomainName,
                zoneId: gatewayDomainName.cloudfrontZoneId,
                evaluateTargetHealth: false,
            },
        ],
    });
    
    const basePathMapping = new aws.apigateway.BasePathMapping("gateway-path-mapping", {
        restApi: api.api.id,
        stageName: api.stage.stageName,
        domainName: gatewayDomainName.domainName,
    });
    
    exports.url = pulumi.interpolate`https://${basePathMapping.domainName}`;
    
    import * as aws from "@pulumi/aws";
    import * as pulumi from "@pulumi/pulumi";
    import * as apigateway from "@pulumi/aws-apigateway";
    
    const hostedZoneName = "example.com";
    const domainName = `myapp.${hostedZoneName}`;
    
    const zone = aws.route53.getZoneOutput({ name: hostedZoneName });
    
    const usEast1 = new aws.Provider("us-east-1", {
        region: "us-east-1",
    });
    
    const certificate = new aws.acm.Certificate(
        "certificate",
        {
            domainName: domainName,
            validationMethod: "DNS",
        },
        { provider: usEast1 },
    );
    
    const validationOption = certificate.domainValidationOptions[0];
    const validationRecord = new aws.route53.Record("certificate-validation-record", {
        name: validationOption.resourceRecordName,
        type: validationOption.resourceRecordType,
        records: [validationOption.resourceRecordValue],
        zoneId: zone.zoneId,
        ttl: 60,
    });
    
    const validation = new aws.acm.CertificateValidation(
        "certificate-validation",
        {
            certificateArn: certificate.arn,
            validationRecordFqdns: [validationRecord.fqdn],
        },
        { provider: usEast1 },
    );
    
    const api = new apigateway.RestAPI("api", {
        routes: [
            {
                path: "/",
                localPath: "www",
            },
        ],
    });
    
    const gatewayDomainName = new aws.apigateway.DomainName(
        "gateway-domain-name",
        {
            certificateArn: certificate.arn,
            domainName,
        },
        { dependsOn: validation },
    );
    
    const gatewayDNSRecord = new aws.route53.Record("gateway-dns-record", {
        zoneId: zone.zoneId,
        type: "A",
        name: domainName,
        aliases: [
            {
                name: gatewayDomainName.cloudfrontDomainName,
                zoneId: gatewayDomainName.cloudfrontZoneId,
                evaluateTargetHealth: false,
            },
        ],
    });
    
    const basePathMapping = new aws.apigateway.BasePathMapping("gateway-path-mapping", {
        restApi: api.api.id,
        stageName: api.stage.stageName,
        domainName: gatewayDomainName.domainName,
    });
    
    export const url = pulumi.interpolate`https://${basePathMapping.domainName}`;
    
    import pulumi
    import pulumi_aws as aws
    import pulumi_aws_apigateway as apigateway
    
    hosted_zone_name = "example.com"
    domain_name = f"myapp.{hosted_zone_name}"
    
    # Look up your existing Route 53 hosted zone.
    zone = aws.route53.get_zone(name=hosted_zone_name)
    
    us_east_1 = aws.Provider(
        "us-east-1",
        aws.ProviderArgs(
            region="us-east-1",
        ),
    )
    
    # Provision a new ACM certificate.
    certificate = aws.acm.Certificate(
        "certificate",
        aws.acm.CertificateArgs(
            domain_name=domain_name,
            validation_method="DNS",
        ),
        opts=pulumi.ResourceOptions(provider=us_east_1),
    )
    
    validation_option = certificate.domain_validation_options[0]
    validation_record = aws.route53.Record(
        "certificate-validation-record",
        aws.route53.RecordArgs(
            name=validation_option["resource_record_name"],
            type=validation_option["resource_record_type"],
            records=[validation_option["resource_record_value"]],
            zone_id=zone.zone_id,
            ttl=60,
        ),
    )
    
    validation = aws.acm.CertificateValidation(
        "certificate-validation",
        aws.acm.CertificateValidationArgs(
            certificate_arn=certificate.arn,
            validation_record_fqdns=[validation_record.fqdn],
        ),
        opts=pulumi.ResourceOptions(provider=us_east_1),
    )
    
    api = apigateway.RestAPI(
        "api",
        routes=[
            apigateway.RouteArgs(
                path="/",
                method=apigateway.Method.GET,
                local_path="www",
            )
        ],
    )
    
    gatewayDomainName = aws.apigateway.DomainName(
        "gateway-domain-name",
        aws.apigateway.DomainNameArgs(
            certificate_arn=certificate.arn,
            domain_name=domain_name,
        ),
        opts=pulumi.ResourceOptions(depends_on=validation),
    )
    
    gateway_dns_record = aws.route53.Record(
        "gateway-dns-record",
        aws.route53.RecordArgs(
            zone_id=zone.zone_id,
            type="A",
            name=domain_name,
            aliases=[
                aws.route53.RecordAliasArgs(
                    name=gatewayDomainName.cloudfront_domain_name,
                    zone_id=gatewayDomainName.cloudfront_zone_id,
                    evaluate_target_health=False,
                )
            ],
        ),
    )
    
    base_path_mapping = aws.apigateway.BasePathMapping(
        "gateway-path-mapping",
        aws.apigateway.BasePathMappingArgs(
            rest_api=api.api.id,
            stage_name=api.stage.stage_name,
            domain_name=gatewayDomainName.domain_name,
        ),
    )
    
    pulumi.export("url", pulumi.Output.concat("https://", base_path_mapping.domain_name))
    
    package main
    
    import (
    	"fmt"
    
    	"github.com/pulumi/pulumi-aws-apigateway/sdk/v2/go/apigateway"
    	"github.com/pulumi/pulumi-aws/sdk/v6/go/aws"
    	"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/acm"
    	awsapigateway "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/apigateway"
    	"github.com/pulumi/pulumi-aws/sdk/v6/go/aws/route53"
    	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
    )
    
    func main() {
    	pulumi.Run(func(ctx *pulumi.Context) error {
    
    		hostedZone := "example.com"
    		domainName := fmt.Sprintf("myapp.%s", hostedZone)
    
    		zone := route53.LookupZoneOutput(ctx, route53.LookupZoneOutputArgs{
    			Name: pulumi.StringPtr(hostedZone),
    		})
    
    		usEast1, err := aws.NewProvider(ctx, "us-east-1", &aws.ProviderArgs{
    			Region: pulumi.StringPtr("us-east-1"),
    		})
    		if err != nil {
    			return err
    		}
    
    		certificate, err := acm.NewCertificate(ctx, "certificate", &acm.CertificateArgs{
    			DomainName:       pulumi.String(domainName),
    			ValidationMethod: pulumi.String("DNS"),
    		}, pulumi.Provider(usEast1))
    		if err != nil {
    			return err
    		}
    
    		validationOption := certificate.DomainValidationOptions.Index(pulumi.Int(0))
    		validationRecord, err := route53.NewRecord(ctx, "certificate-validation-record", &route53.RecordArgs{
    			Name: validationOption.ResourceRecordName().Elem(),
    			Type: validationOption.ResourceRecordType().Elem(),
    			Records: pulumi.StringArray{
    				validationOption.ResourceRecordValue().Elem(),
    			},
    			ZoneId: zone.ZoneId(),
    			Ttl:    pulumi.Int(60),
    		})
    		if err != nil {
    			return err
    		}
    
    		validation, err := acm.NewCertificateValidation(ctx, "certificate-validation", &acm.CertificateValidationArgs{
    			CertificateArn: certificate.Arn,
    			ValidationRecordFqdns: pulumi.StringArray{
    				validationRecord.Fqdn,
    			},
    		}, pulumi.Provider(usEast1))
    		if err != nil {
    			return err
    		}
    
    		methodGET := apigateway.MethodGET
    		api, err := apigateway.NewRestAPI(ctx, "api", &apigateway.RestAPIArgs{
    			Routes: []apigateway.RouteArgs{
    				{
    					Path:      "/",
    					Method:    &methodGET,
    					LocalPath: pulumi.StringRef("www"),
    				},
    			},
    		})
    		if err != nil {
    			return err
    		}
    
    		gatewayDomainName, err := awsapigateway.NewDomainName(ctx, "gateway-domain-name", &awsapigateway.DomainNameArgs{
    			CertificateArn: certificate.Arn,
    			DomainName:     pulumi.String(domainName),
    		}, pulumi.DependsOn([]pulumi.Resource{validation}))
    		if err != nil {
    			return err
    		}
    
    		_, err = route53.NewRecord(ctx, "gateway-dns-record", &route53.RecordArgs{
    			ZoneId: zone.ZoneId(),
    			Type:   pulumi.String("A"),
    			Name:   pulumi.String(domainName),
    			Aliases: route53.RecordAliasArray{
    				route53.RecordAliasArgs{
    					Name:                 gatewayDomainName.CloudfrontDomainName,
    					ZoneId:               gatewayDomainName.CloudfrontZoneId,
    					EvaluateTargetHealth: pulumi.Bool(false),
    				},
    			},
    		})
    		if err != nil {
    			return err
    		}
    
    		apiID := api.Api.ApplyT(func(api *awsapigateway.RestApi) pulumi.StringOutput {
    			return api.ID().ToStringOutput()
    		})
    
    		basePathMapping, err := awsapigateway.NewBasePathMapping(ctx, "gateway-path-mapping", &awsapigateway.BasePathMappingArgs{
    			RestApi:    apiID,
    			StageName:  api.Stage.StageName(),
    			DomainName: gatewayDomainName.DomainName,
    		})
    		if err != nil {
    			return err
    		}
    
    		ctx.Export("url", pulumi.Sprintf("http://%s", basePathMapping.DomainName))
    		return nil
    	})
    }
    
    using System.Collections.Generic;
    using Pulumi;
    using ApiGateway = Pulumi.AwsApiGateway;
    using Aws = Pulumi.Aws;
    
    return await Deployment.RunAsync(() =>
    {
        var hostedZoneName = "example.com";
        var domainName = $"myapp.{hostedZoneName}";
    
        var zone = Aws.Route53.GetZone.Invoke(new()
        {
            Name = hostedZoneName,
        });
    
        var usEast1 = new Aws.Provider("us-east-1", new()
        {
            Region = "us-east-1",
        });
    
        var certificate = new Aws.Acm.Certificate("certificate", new() {
            DomainName = domainName,
            ValidationMethod = "DNS",
        }, new CustomResourceOptions { Provider = usEast1 });
    
        var validationOption = certificate.DomainValidationOptions.GetAt(0);
        var validationRecord = new Aws.Route53.Record("certificate-validation", new()
        {
            Name = validationOption.Apply(option => option.ResourceRecordName!),
            Type = validationOption.Apply(option => option.ResourceRecordType!),
            Records = { validationOption.Apply(option => option.ResourceRecordValue!), },
            ZoneId = zone.Apply(zone => zone.ZoneId),
            Ttl = 60,
        });
    
        var validation = new Aws.Acm.CertificateValidation("certificate-validation", new()
        {
            CertificateArn = certificate.Arn,
            ValidationRecordFqdns = { validationRecord.Fqdn },
        },  new CustomResourceOptions { Provider = usEast1 });
    
        var api = new ApiGateway.RestAPI("api", new()
        {
            Routes =
            {
                new ApiGateway.Inputs.RouteArgs {
                    Path = "/",
                    LocalPath = "www",
                },
            },
        });
    
        var gatewayDomainName = new Aws.ApiGateway.DomainName("gateway-domain-name", new()
        {
            CertificateArn = certificate.Arn,
            Domain = domainName,
        }, new CustomResourceOptions { DependsOn = validation });
    
        var gatewayDNSRecord = new Aws.Route53.Record("gateway-dns-record", new()
        {
            ZoneId = zone.Apply(zone => zone.ZoneId),
            Type = "A",
            Name = domainName,
            Aliases =
            {
                new Aws.Route53.Inputs.RecordAliasArgs
                {
                    Name = gatewayDomainName.CloudfrontDomainName,
                    ZoneId = gatewayDomainName.CloudfrontZoneId,
                    EvaluateTargetHealth = true,
                },
            },
        });
    
        var basePathMapping = new Aws.ApiGateway.BasePathMapping("gateway-path-mapping", new()
        {
            RestApi = api.Api.Apply(api => api.Id),
            StageName = api.Stage.Apply(stage => stage.StageName),
            DomainName = gatewayDomainName.Domain,
        });
    
        return new Dictionary<string, object?>
        {
            ["url"] = Output.Format($"https://{basePathMapping.DomainName}/"),
        };
    });
    
    package myproject;
    
    import java.util.List;
    
    import com.pulumi.Pulumi;
    import com.pulumi.core.Either;
    import com.pulumi.core.Output;
    import com.pulumi.resources.CustomResourceOptions;
    import com.pulumi.aws.Provider;
    import com.pulumi.aws.ProviderArgs;
    import com.pulumi.aws.acm.Certificate;
    import com.pulumi.aws.acm.CertificateArgs;
    import com.pulumi.aws.acm.CertificateValidation;
    import com.pulumi.aws.acm.CertificateValidationArgs;
    import com.pulumi.aws.apigateway.BasePathMapping;
    import com.pulumi.aws.apigateway.BasePathMappingArgs;
    import com.pulumi.aws.apigateway.DomainName;
    import com.pulumi.aws.apigateway.DomainNameArgs;
    import com.pulumi.aws.route53.Record;
    import com.pulumi.aws.route53.RecordArgs;
    import com.pulumi.aws.route53.Route53Functions;
    import com.pulumi.aws.route53.inputs.GetZoneArgs;
    import com.pulumi.aws.route53.inputs.RecordAliasArgs;
    import com.pulumi.awsapigateway.RestAPI;
    import com.pulumi.awsapigateway.RestAPIArgs;
    import com.pulumi.awsapigateway.inputs.RouteArgs;
    
    public class App {
        public static void main(String[] args) {
            Pulumi.run(ctx -> {
    
                var hostedZoneName = "example.com";
                var domainName = String.format("myapp.%s", hostedZoneName);
    
                var zone = Route53Functions.getZone(GetZoneArgs.builder()
                    .name(hostedZoneName)
                    .build());
    
                var usEast1 = new Provider("us-east-1", ProviderArgs.builder()
                    .region("us-east-1")
                    .build());
    
                var certificate = new Certificate("cert", CertificateArgs.builder()
                    .domainName(domainName)
                    .validationMethod("DNS")
                    .build(), CustomResourceOptions.builder()
                        .provider(usEast1)
                        .build());
    
                var validationOption = certificate.domainValidationOptions().applyValue(o -> o.get(0));
                var validationRecord = new Record("certificate-validation-record", RecordArgs.builder()
                    .name(validationOption.apply(o -> Output.of(o.resourceRecordName().get())))
                    .type(validationOption.apply(o -> Output.of(Either.ofLeft(o.resourceRecordType().get()))))
                    .zoneId(zone.applyValue(z -> z.zoneId()))
                    .records(validationOption.applyValue(o -> List.of(o.resourceRecordValue().get())))
                    .ttl(60)
                    .build());
    
                var validation = new CertificateValidation("certificate-validation", CertificateValidationArgs.builder()
                    .certificateArn(certificate.arn())
                    .validationRecordFqdns(validationRecord.fqdn().applyValue(fqdn -> List.of(fqdn)))
                    .build(), CustomResourceOptions.builder()
                        .provider(usEast1)
                        .build());
    
                var api = new RestAPI("api", RestAPIArgs.builder()
                    .routes(new RouteArgs[]{
                        RouteArgs.builder()
                            .path("/")
                            .localPath("www")
                        .build()
                    })
                .build());
    
                var gatewayDomainName = new DomainName("gateway-domain-name", DomainNameArgs.builder()
                    .certificateArn(certificate.arn())
                    .domainName(domainName)
                    .build(), CustomResourceOptions.builder()
                        .dependsOn(List.of(validation))
                        .build());
    
                var gatewayDNSRecord = new Record("gateway-dns-record", RecordArgs.builder()
                    .zoneId(zone.applyValue(z -> z.zoneId()))
                    .type("A")
                    .name(domainName)
                    .aliases(RecordAliasArgs.builder()
                        .name(gatewayDomainName.cloudfrontDomainName())
                        .zoneId(gatewayDomainName.cloudfrontZoneId())
                        .evaluateTargetHealth(false)
                        .build())
                    .build());
    
                var basePathMapping = new BasePathMapping("gateway-path-mapping", BasePathMappingArgs.builder()
                    .restApi(api.api().apply(v -> v.id()))
                    .stageName(api.stage().apply(n -> n.stageName()))
                    .domainName(gatewayDomainName.domainName())
                    .build());
    
                ctx.export("url", Output.format("https://%s", basePathMapping.domainName()));
            });
        }
    }
    
    name: awsx-apigateway-custom-domain-yaml
    runtime: yaml
    description: An example that deploys an API Gateway REST API with a custom domain from Route53.
    
    variables:
      hostedZoneName: example.com
      domainName: myapp.${hostedZoneName}
      zone:
        fn::invoke:
          function: aws:route53:getZone
          arguments:
            name: ${hostedZoneName}
    
    resources:
      usEast1:
        type: pulumi:providers:aws
        properties:
          region: us-east-1
    
      certificate:
        type: aws:acm:Certificate
        properties:
          domainName: ${domainName}
          validationMethod: DNS
        options:
          provider: ${usEast1}
    
      validationRecord:
        type: aws:route53:Record
        properties:
          name: ${certificate.domainValidationOptions[0].resourceRecordName}
          type: ${certificate.domainValidationOptions[0].resourceRecordType}
          records:
            - ${certificate.domainValidationOptions[0].resourceRecordValue}
          zoneId: ${zone.zoneId}
          ttl: 60
    
      validation:
        type: aws:acm:CertificateValidation
        properties:
          certificateArn: ${certificate.arn}
          validationRecordFqdns:
            - ${validationRecord.fqdn}
        options:
          provider: ${usEast1}
    
      api:
        type: aws-apigateway:RestAPI
        properties:
          routes:
            - path: /
              localPath: www
    
      gatewayDomainName:
        type: aws:apigateway:DomainName
        properties:
          certificateArn: ${certificate.arn}
          domainName: ${domainName}
        options:
          dependsOn:
            - ${validation}
    
      gatewayDNSRecord:
        type: aws:route53:Record
        properties:
          zoneId: ${zone.zoneId}
          type: A
          name: ${domainName}
          aliases:
            - name: ${gatewayDomainName.cloudfrontDomainName}
              zoneId: ${gatewayDomainName.cloudfrontZoneId}
              evaluateTargetHealth: false
    
      basePathMapping:
        type: aws:apigateway:BasePathMapping
        properties:
          restApi: ${api.api.id}
          stageName: ${api.stage.stageName}
          domainName: ${gatewayDomainName.domainName}
    
    outputs:
      url: https://${basePathMapping.domainName}
    

    For more information about the options and levels of customizability available for edge-optimized API Gateways and custom domains, refer to Set up Custom Domain Name for an API in API Gateway in the AWS documentation.

    OpenAPI

    Amazon API Gateway supports the OpenAPI specification (formerly known as “Swagger”) for defining APIs. Using OpenAPI to define your APIs eases integration with other API authoring, modeling, and testing tools, at some added complexity cost as you will need to understand the mechanics of how API Gateway works and what HTTP headers it uses to accomplish its integrations.

    Defining an Entire Endpoint

    To use an OpenAPI specification to initialize your API Gateway, supply an entire OpenAPI specification as a JSON string in the swaggerString property. For example, this API proxies a route through to another HTTP endpoint by setting up an http_proxy integration, much like the example above:

    "use strict";
    const pulumi = require("@pulumi/pulumi");
    const apigateway = require("@pulumi/aws-apigateway");
    
    const api = new apigateway.RestAPI("api", {
        swaggerString: JSON.stringify({
            "swagger": "2.0",
            "info": {
                title: "example",
                version: "1.0",
            },
            "paths": {
                "/": {
                    get: {
                        "x-amazon-apigateway-integration": {
                            httpMethod: "GET",
                            passthroughBehavior: "when_no_match",
                            type: "http_proxy",
                            uri: "https://httpbin.org/uuid",
                        },
                    },
                },
            },
            "x-amazon-apigateway-binary-media-types": ["*/*"],
        }),
    });
    
    exports.url = api.url;
    
    import * as pulumi from "@pulumi/pulumi";
    import * as apigateway from "@pulumi/aws-apigateway";
    
    const api = new apigateway.RestAPI("api", {
        swaggerString: JSON.stringify({
            "swagger": "2.0",
            "info": {
                title: "example",
                version: "1.0",
            },
            "paths": {
                "/": {
                    get: {
                        "x-amazon-apigateway-integration": {
                            httpMethod: "GET",
                            passthroughBehavior: "when_no_match",
                            type: "http_proxy",
                            uri: "https://httpbin.org/uuid",
                        },
                    },
                },
            },
            "x-amazon-apigateway-binary-media-types": ["*/*"],
        }),
    });
    
    export const url = api.url;
    
    import json
    import pulumi
    import pulumi_aws_apigateway as apigateway
    
    api = apigateway.RestAPI("api", apigateway.RestAPIArgs(
        swagger_string=json.dumps(
            {
                "swagger": "2.0",
                "info": {
                    "title": "example",
                    "version": "1.0",
                },
                "paths": {
                    "/": {
                        "get": {
                            "x-amazon-apigateway-integration": {
                                "httpMethod": "GET",
                                "passthroughBehavior": "when_no_match",
                                "type": "http_proxy",
                                "uri": "https://httpbin.org/uuid",
                            },
                        },
                    },
                },
                "x-amazon-apigateway-binary-media-types": ["*/*"],
            }
        )),
    )
    
    pulumi.export("url", api.url)
    
    package main
    
    import (
    	"github.com/pulumi/pulumi-aws-apigateway/sdk/v2/go/apigateway"
    	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
    )
    
    func main() {
    	pulumi.Run(func(ctx *pulumi.Context) error {
    
    		api, err := apigateway.NewRestAPI(ctx, "api", &apigateway.RestAPIArgs{
    			SwaggerString: pulumi.String(`{
    				"swagger": "2.0",
    				"info": {
    					"title": "example",
    					"version": "1.0"
    				},
    				"paths": {
    					"/": {
    						"get": {
    							"x-amazon-apigateway-integration": {
    							"httpMethod": "GET",
    							"passthroughBehavior": "when_no_match",
    							"type": "http_proxy",
    							"uri": "https://httpbin.org/uuid"
    							}
    						}
    					}
    				},
    				"x-amazon-apigateway-binary-media-types": ["*/*"]
    			}`),
    		})
    		if err != nil {
    			return err
    		}
    
    		ctx.Export("url", api.Url)
    		return nil
    	})
    }
    
    using System;
    using System.Collections.Generic;
    using System.Text.Json;
    using Pulumi;
    using AwsApiGateway = Pulumi.AwsApiGateway;
    
    return await Deployment.RunAsync(() =>
    {
        var api = new AwsApiGateway.RestAPI("api", new()
        {
            SwaggerString = JsonSerializer.Serialize(new Dictionary<string, object>() {
                ["swagger"] = "2.0",
                ["info"] = new {
                    title = "example",
                    version = "1.0",
                },
                ["paths"] = new Dictionary<string, object>() {
                    ["/"] = new {
                        get = new Dictionary<string, object>() {
                            ["x-amazon-apigateway-integration"] = new {
                                httpMethod = "GET",
                                passthroughBehavior = "when_no_match",
                                type = "http_proxy",
                                uri = "https://httpbin.org/uuid",
                            },
                        },
                    },
                },
                ["x-amazon-apigateway-binary-media-types"] = new[] {
                    "*/*"
                },
            }),
        });
    
        return new Dictionary<string, object?>
        {
            ["url"] = api.Url,
        };
    });
    
    package myproject;
    
    import com.pulumi.Pulumi;
    import com.pulumi.core.Output;
    import com.pulumi.aws.s3.Bucket;
    import com.pulumi.awsapigateway.RestAPI;
    import com.pulumi.awsapigateway.RestAPIArgs;
    import static com.pulumi.codegen.internal.Serialization.*;
    
    public class App {
        public static void main(String[] args) {
            Pulumi.run(ctx -> {
    
                var api = new RestAPI("api", RestAPIArgs.builder()
                    .swaggerString(serializeJson(jsonObject(
                        jsonProperty("swagger", "2.0"),
                        jsonProperty("info", jsonObject(
                            jsonProperty("title", "example"),
                            jsonProperty("version", "1.0")
                        )),
                        jsonProperty("paths", jsonObject(
                            jsonProperty("/", jsonObject(
                                jsonProperty("get", jsonObject(
                                    jsonProperty("x-amazon-apigateway-integration", jsonObject(
                                        jsonProperty("httpMethod", "GET"),
                                        jsonProperty("passthroughBehavior", "when_no_match"),
                                        jsonProperty("type", "http_proxy"),
                                        jsonProperty("uri", "https://httpbin.org/uuid")
                                    ))
                                ))
                            ))
                        )),
                        jsonProperty("x-amazon-apigateway-binary-media-types", jsonArray(
                            "*/*"
                        ))
                    )))
                    .build());
    
                ctx.export("url", api.url());
            });
        }
    }
    
    name: awsx-apigateway-openapi-full-yaml
    runtime: yaml
    description: An example of configuring an API Gateway instance with an OpenAPI/Swagger JSON definition.
    
    resources:
      api:
        type: aws-apigateway:RestAPI
        properties:
          swaggerString: |
            {
              "swagger": "2.0",
              "info": {
                "title": "example",
                "version": "1.0"
              },
              "paths": {
                "/": {
                  "get": {
                    "x-amazon-apigateway-integration": {
                      "httpMethod": "GET",
                      "passthroughBehavior": "when_no_match",
                      "type": "http_proxy",
                      "uri": "https://httpbin.org/uuid"
                    }
                  }
                }
              },
              "x-amazon-apigateway-binary-media-types": ["*/*"]
            }        
    
    outputs:
      url: ${api.url}
    

    Requests for the exported URL are passed directly to the configured backend:

    $ curl $(pulumi stack output url)
    {
      "uuid": "afb17cf3-7a70-4c4b-9f09-7e8f23a63b2b"
    }
    

    This is more complex than the above examples, but an escape hatch that you can use to access any API Gateway features not yet supported by the easier abstractions in Pulumi Crosswalk for AWS API Gateway. You must manually provide permission for any route targets to be invoked by API Gateway when using this option.

    Defining a Single Route

    Being able to provide an OpenAPI specification for an entire API Gateway lets you take matters into your own hands when you need access to a feature that isn’t supported directly by apigateway.RestAPI. However, you can also define just a single API route (a “raw data” route) using OpenAPI using the data property.

    The data property is just the x-amazon-apigateway-integration object, which can be seen in the above example. The route’s other parameters, such as its path and method, otherwise use the same approaches seen earlier.

    For instance, the same API Gateway endpoint that proxies through to another API can be authored as follows:

    "use strict";
    const apigateway = require("@pulumi/aws-apigateway");
    
    const api = new apigateway.RestAPI("api", {
        routes: [
            {
                path: "/",
                method: "GET",
                data: {
                    "x-amazon-apigateway-integration": {
                        httpMethod: "GET",
                        passthroughBehavior: "when_no_match",
                        type: "http_proxy",
                        uri: "https://httpbin.org/uuid",
                    },
                },
            },
        ],
    });
    
    exports.url = api.url;
    
    const apigateway = require("@pulumi/aws-apigateway");
    
    const api = new apigateway.RestAPI("api", {
        routes: [
            {
                path: "/",
                method: "GET",
                data: {
                    "x-amazon-apigateway-integration": {
                        httpMethod: "GET",
                        passthroughBehavior: "when_no_match",
                        type: "http_proxy",
                        uri: "https://httpbin.org/uuid",
                    },
                },
            },
        ],
    });
    
    exports.url = api.url;
    
    import pulumi
    import pulumi_aws_apigateway as apigateway
    
    api = apigateway.RestAPI(
        "api",
        routes=[
            apigateway.RouteArgs(
                path="/",
                method=apigateway.Method.GET,
                data={
                    "x-amazon-apigateway-integration": {
                        "httpMethod": "GET",
                        "passthroughBehavior": "when_no_match",
                        "type": "http_proxy",
                        "uri": "https://httpbin.org/uuid",
                    },
                },
            ),
        ],
    )
    
    pulumi.export("url", api.url)
    
    package main
    
    import (
    	"github.com/pulumi/pulumi-aws-apigateway/sdk/v2/go/apigateway"
    	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
    )
    
    func main() {
    	pulumi.Run(func(ctx *pulumi.Context) error {
    
    		GET := apigateway.MethodGET
    		api, err := apigateway.NewRestAPI(ctx, "api", &apigateway.RestAPIArgs{
    			Routes: []apigateway.RouteArgs{
    				{
    					Path:   "/",
    					Method: &GET,
    					Data: map[string]interface{}{
    						"x-amazon-apigateway-integration": map[string]interface{}{
    							"httpMethod":          "GET",
    							"passthroughBehavior": "when_no_match",
    							"type":                "http_proxy",
    							"uri":                 "https://httpbin.org/uuid",
    						},
    					},
    				},
    			},
    		})
    		if err != nil {
    			return err
    		}
    
    		ctx.Export("url", api.Url)
    		return nil
    	})
    }
    
    using System.Collections.Generic;
    using System.Text.Json;
    using Pulumi;
    using AwsApiGateway = Pulumi.AwsApiGateway;
    
    return await Deployment.RunAsync(() =>
    {
        var api = new AwsApiGateway.RestAPI("api", new()
        {
            Routes =
            {
                new AwsApiGateway.Inputs.RouteArgs
                {
                    Path = "/",
                    Method = AwsApiGateway.Method.GET,
                    Data = JsonSerializer.Deserialize<object>(JsonSerializer.Serialize(new Dictionary<string, object>() {
                        ["x-amazon-apigateway-integration"] = new {
                            httpMethod = "GET",
                            passthroughBehavior = "when_no_match",
                            type = "http_proxy",
                            uri = "https://httpbin.org/uuid",
                        },
                    })),
                },
            },
        });
    
        return new Dictionary<string, object?>
        {
            ["url"] = api.Url,
        };
    });
    
    package myproject;
    
    import com.pulumi.Pulumi;
    import com.pulumi.awsapigateway.enums.Method;
    import com.pulumi.awsapigateway.RestAPI;
    import com.pulumi.awsapigateway.RestAPIArgs;
    import com.pulumi.awsapigateway.inputs.RouteArgs;
    import static com.pulumi.codegen.internal.Serialization.*;
    
    public class App {
        public static void main(String[] args) {
            Pulumi.run(ctx -> {
    
                var api = new RestAPI("api", RestAPIArgs.builder()
                    .routes(new RouteArgs[]{
                        RouteArgs.builder()
                            .path("/")
                            .method(Method.GET)
                            .data(jsonObject(
                                jsonProperty("x-amazon-apigateway-integration", jsonObject(
                                    jsonProperty("httpMethod", "GET"),
                                    jsonProperty("passthroughBehavior", "when_no_match"),
                                    jsonProperty("type", "http_proxy"),
                                    jsonProperty("uri", "https://httpbin.org/uuid")
                                ))
                            ))
                            .build(),
                    })
                    .build());
    
                ctx.export("url", api.url());
            });
        }
    }
    
    name: awsx-apigateway-openapi-route-yaml
    runtime: yaml
    description: n example of configuring an API Gateway route with an OpenAPI/Swagger definition.
    outputs:
      # Export the name of the bucket
      bucketName: ${my-bucket.id}
    resources:
      # Create an AWS resource (S3 Bucket)
      my-bucket:
        type: aws:s3:Bucket
    

    Requests are handled similarly:

    $ curl $(pulumi stack output url)
    {
      "uuid": "6cfb94ae-1655-4697-b413-89e541b027f4"
    }
    

    For more information about API Gateway’s support for OpenAPI, including exporting specifications from existing APIs for consumption from other tools, see Documenting a REST API in API Gateway in the AWS documentation. For full details on what the OpenAPI integration object may contain, see the x-amazon-apigateway-integration Object documentation.

    Additional API Gateway Resources

    For more details about Amazon API Gateway and REST APIs, see the following resources:

      PulumiUP 2024. Watch On Demand.