---
title: API Gateway
url: /docs/iac/guides/clouds/aws/api-gateway/
---
[Amazon API Gateway](https://aws.amazon.com/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.

## Overview

The [AWS API Gateway component](/registry/packages/aws-apigateway/), available in the Pulumi Registry, provides an easier way to manage API Gateway resources. It uses 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.

## Creating and configuring routes

AWS API Gateway creates REST APIs that:

- Are HTTP based.
- Adhere to the [REST](https://en.wikipedia.org/wiki/Representational_state_transfer) 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.

> **Note:** Internally the API Gateway resource uses a collection of supporting objects, like resources, methods, and more,
however one of the benefits of the AWS API Gateway component 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 the AWS API Gateway component:

- [Lambda Function Event Handler Route](#lambda)
- [Static Route Served by S3](#s3)
- [Integration Route](#integration)
- [OpenAPI Specification for an Entire Endpoint](#openapi-full)
- [OpenAPI Specification for a Single Route](#openapi-route)

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

### Handling requests with Lambda {#lambda}

An event-handler route is an API that will map to a [Lambda function](https://aws.amazon.com/lambda/). 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.

<!-- chooser: language -->

<!-- option: typescript -->

```typescript
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;

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-lambda-typescript)

<!-- /option -->

<!-- option: python -->

```python
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)

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-lambda-python)

<!-- /option -->

<!-- option: go -->

```go
package main

import (
	"encoding/json"

	"github.com/pulumi/pulumi-aws-apigateway/sdk/v3/go/apigateway"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/iam"
	"github.com/pulumi/pulumi-aws/sdk/v7/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
	})
}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-lambda-go)

<!-- /option -->

<!-- option: csharp -->

```csharp
﻿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,
    };
});

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-lambda-csharp)

<!-- /option -->

<!-- option: java -->

```java
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());
        });
    }
}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-lambda-java)

<!-- /option -->

<!-- option: yaml -->

```yaml
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}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-lambda-yaml)

<!-- /option -->

<!-- /chooser -->

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:

```bash
$ 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:

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

For more complete information about creating Lambda functions, see the [AWS Lambda guide](/docs/clouds/aws/guides/lambda/).

### Serving static files from S3 {#s3}

A Static Route serves static content from [S3](https://aws.amazon.com/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:

<!-- chooser: language -->

<!-- option: typescript -->

```typescript
import * as apigateway from "@pulumi/aws-apigateway";

const api = new apigateway.RestAPI("api", {
    routes: [{
            path: "/",
            localPath: "www",
        },
    ],
});

export const url = api.url;

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-s3-typescript)

<!-- /option -->

<!-- option: python -->

```python
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)

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-s3-python)

<!-- /option -->

<!-- option: go -->

```go
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
	})
}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-s3-go)

<!-- /option -->

<!-- option: csharp -->

```csharp
﻿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,
    };
});

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-s3-csharp)

<!-- /option -->

<!-- option: java -->

```java
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());
        });
    }
}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-s3-java)

<!-- /option -->

<!-- option: yaml -->

```yaml
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}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-s3-yaml)

<!-- /option -->

<!-- /chooser -->

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

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

By default, any index documents will be automatically served by S3 when directories are retrieved over HTTP.
(See [Configuring an Index Document](https://docs.aws.amazon.com/AmazonS3/latest/dev/IndexDocumentSupport.html) 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 {#integration}

If neither of the above route types work for you, [Amazon API Gateway integrations](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-api-integration-types.html) 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`:

<!-- chooser: language -->

<!-- option: typescript -->

```typescript
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;

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-http-proxy-typescript)

<!-- /option -->

<!-- option: python -->

```python
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)

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-http-proxy-python)

<!-- /option -->

<!-- option: go -->

```go
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
	})
}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-http-proxy-go)

<!-- /option -->

<!-- option: csharp -->

```csharp
﻿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,
    };
});

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-http-proxy-csharp)

<!-- /option -->

<!-- option: java -->

```java
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());
        });
    }
}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-http-proxy-java)

<!-- /option -->

<!-- option: yaml -->

```yaml
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}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-http-proxy-yaml)

<!-- /option -->

<!-- /chooser -->

## Controlling Access to APIs {#authorizers}

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](/registry/packages/aws/), and are described in depth in the article [Controlling and Managing Access to a REST API in API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-control-access-to-api.html).

### Cognito Authorizers

[Cognito Authorizers](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-integrate-with-cognito.html) allow you to use [Amazon Cognito User Pools](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools.html) 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:

<!-- chooser: language -->

<!-- option: typescript -->

```typescript
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;

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-auth-cognito-typescript)

<!-- /option -->

<!-- option: python -->

```python
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)

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-auth-cognito-python)

<!-- /option -->

<!-- option: go -->

```go
package main

import (
	"github.com/pulumi/pulumi-aws-apigateway/sdk/v3/go/apigateway"
	"github.com/pulumi/pulumi-aws/sdk/v7/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
	})
}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-auth-cognito-go)

<!-- /option -->

<!-- option: csharp -->

```csharp
﻿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 };
});

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-auth-cognito-csharp)

<!-- /option -->

<!-- option: java -->

```java
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());
        });
    }
}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-auth-cognito-java)

<!-- /option -->

<!-- option: yaml -->

```yaml
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}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-auth-cognito-yaml)

<!-- /option -->

<!-- /chooser -->

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](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html) 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](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-lambda-authorizer-input.html) and responds with a valid [authorizer response](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-lambda-authorizer-output.html). See [AWS Lambda](/docs/clouds/aws/guides/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.)

<!-- chooser: language -->

<!-- option: typescript -->

```typescript
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;

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-auth-lambda-typescript)

<!-- /option -->

<!-- option: python -->

```python
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)

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-auth-lambda-python)

<!-- /option -->

<!-- option: go -->

```go
package main

import (
	"encoding/json"

	"github.com/pulumi/pulumi-aws-apigateway/sdk/v3/go/apigateway"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/iam"
	"github.com/pulumi/pulumi-aws/sdk/v7/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
	})
}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-auth-lambda-go)

<!-- /option -->

<!-- option: csharp -->

```csharp
﻿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 };
});

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-auth-lambda-csharp)

<!-- /option -->

<!-- option: java -->

```java
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());
        });
    }
}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-auth-lambda-java)

<!-- /option -->

<!-- option: yaml -->

```yaml
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}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-auth-lambda-yaml)

<!-- /option -->

<!-- /chooser -->

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

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

$ curl $(pulumi stack output url)
{"message":"Unauthorized"}
```

For additional information about API Gateway Lambda Authorizers, see the
[AWS documentation](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html).

## Request Validation {#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:

<!-- chooser: language -->

<!-- option: typescript -->

```typescript
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;

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-validation-types-typescript)

<!-- /option -->

<!-- option: python -->

```python
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)

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-validation-types-python)

<!-- /option -->

<!-- option: go -->

```go
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
	})
}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-validation-types-go)

<!-- /option -->

<!-- option: csharp -->

```csharp
﻿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,
    };
});

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-validation-types-csharp)

<!-- /option -->

<!-- option: java -->

```java
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());
        });
    }
}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-validation-types-java)

<!-- /option -->

<!-- option: yaml -->

```yaml
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}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-validation-types-yaml)

<!-- /option -->

<!-- /chooser -->

### 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:

<!-- chooser: language -->

<!-- option: typescript -->

```typescript
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;

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-validation-types-typescript)

<!-- /option -->

<!-- option: python -->

```python
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)

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-validation-types-python)

<!-- /option -->

<!-- option: go -->

```go
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
	})
}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-validation-types-go)

<!-- /option -->

<!-- option: csharp -->

```csharp
﻿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,
    };
});

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-validation-types-csharp)

<!-- /option -->

<!-- option: java -->

```java
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());
        });
    }
}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-validation-types-java)

<!-- /option -->

<!-- option: yaml -->

```yaml
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}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-validation-types-yaml)

<!-- /option -->

<!-- /chooser -->

For more information about request validation, see [Use Request Validation in API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-method-request-validation.html#api-gateway-request-validation-basic-definitions) in the AWS documentation.

> **Note:** Request body validation is not yet supported. To follow progress or share your use case, comment on [this open issue](https://github.com/pulumi/pulumi-aws-apigateway/issues/36).

### 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
1. Defining a usage plan for the API (which can optionally define quotas and throttling rules)
1. 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):

<!-- chooser: language -->

<!-- option: typescript -->

```typescript
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;

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-api-keys-typescript)

<!-- /option -->

<!-- option: python -->

```python
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)

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-api-keys-python)

<!-- /option -->

<!-- option: go -->

```go
package main

import (
	"github.com/pulumi/pulumi-aws-apigateway/sdk/v3/go/apigateway"
	awsapigateway "github.com/pulumi/pulumi-aws/sdk/v7/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
	})
}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-api-keys-go)

<!-- /option -->

<!-- option: csharp -->

```csharp
﻿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,
    };
});

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-api-keys-csharp)

<!-- /option -->

<!-- option: java -->

```java
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());
        });
    }
}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-api-keys-java)

<!-- /option -->

<!-- option: yaml -->

```yaml
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}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-api-keys-yaml)

<!-- /option -->

<!-- /chooser -->

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

```bash
$ 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](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-api-usage-plans.html).

## Custom Domains and SSL {#custom-domain}

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)](https://aws.amazon.com/cloudfront/) 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)](https://docs.aws.amazon.com/acm/latest/userguide/acm-overview.html). (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.

<!-- chooser: language -->

<!-- option: typescript -->

```typescript
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}`;

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-custom-domain-typescript)

<!-- /option -->

<!-- option: python -->

```python
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))

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-custom-domain-python)

<!-- /option -->

<!-- option: go -->

```go
package main

import (
	"fmt"

	"github.com/pulumi/pulumi-aws-apigateway/sdk/v2/go/apigateway"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws"
	"github.com/pulumi/pulumi-aws/sdk/v7/go/aws/acm"
	awsapigateway "github.com/pulumi/pulumi-aws/sdk/v7/go/aws/apigateway"
	"github.com/pulumi/pulumi-aws/sdk/v7/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
	})
}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-custom-domain-go)

<!-- /option -->

<!-- option: csharp -->

```csharp
﻿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}/"),
    };
});

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-custom-domain-csharp)

<!-- /option -->

<!-- option: java -->

```java
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()));
        });
    }
}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-custom-domain-java)

<!-- /option -->

<!-- option: yaml -->

```yaml
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}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-custom-domain-yaml)

<!-- /option -->

<!-- /chooser -->

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](https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-custom-domains.html) in the AWS documentation.

## OpenAPI {#openapi}

Amazon API Gateway supports the [OpenAPI specification](https://swagger.io/docs/specification/about/) (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 {#openapi-full}

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](#integration):

<!-- chooser: language -->

<!-- option: typescript -->

```typescript
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;

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-openapi-full-typescript)

<!-- /option -->

<!-- option: python -->

```python
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)

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-openapi-full-python)

<!-- /option -->

<!-- option: go -->

```go
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
	})
}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-openapi-full-go)

<!-- /option -->

<!-- option: csharp -->

```csharp
﻿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,
    };
});

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-openapi-full-csharp)

<!-- /option -->

<!-- option: java -->

```java
package myproject;

import com.pulumi.Pulumi;
import com.pulumi.core.Output;
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());
        });
    }
}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-openapi-full-java)

<!-- /option -->

<!-- option: yaml -->

```yaml
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}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-openapi-full-yaml)

<!-- /option -->

<!-- /chooser -->

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

```bash
$ 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 API Gateway component. You must manually
provide permission for any route targets to be invoked by API Gateway when using this option.

### Defining a Single Route {#openapi-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:

<!-- chooser: language -->

<!-- option: typescript -->

```typescript
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;

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-openapi-route-typescript)

<!-- /option -->

<!-- option: python -->

```python
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)

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-openapi-route-python)

<!-- /option -->

<!-- option: go -->

```go
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
	})
}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-openapi-route-go)

<!-- /option -->

<!-- option: csharp -->

```csharp
﻿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,
    };
});

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-openapi-route-csharp)

<!-- /option -->

<!-- option: java -->

```java
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());
        });
    }
}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-openapi-route-java)

<!-- /option -->

<!-- option: yaml -->

```yaml
name: awsx-apigateway-openapi-route-yaml
runtime: yaml
description: An 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

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-apigateway-openapi-route-yaml)

<!-- /option -->

<!-- /chooser -->

Requests are handled similarly:

```bash
$ 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](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-documenting-api.html) in the AWS documentation. For full details on what the OpenAPI integration object may contain, see the
[x-amazon-apigateway-integration Object documentation](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-swagger-extensions-integration.html).

## Additional API Gateway Resources

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

- [Use API Gateway to Create REST APIs](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-overview-developer-experience.html#api-gateway-overview-rest)

