Inspired by Luke's answer
AWS API Gateway natively supports Velocity (a Java-based template engine) which enables us to dynamically set the redirect URL and even set cookies based on the incoming request (headers, query params, body, etc).
Here is a 302 redirect example without the use of Lambda:
# AWS Console > API Gateway > Create API > REST API > Import > Import from Swagger or Open API 3
openapi: 3.0.1
info:
title: 'API Gateway redirect without Lambda. Powered by API Gateway Mock Integration'
description: 'Accept a query parameters: "url" as the destination (optional), "pid" as the affiliate partner tracking ID cookie value (optional)'
version: ''
paths:
"/redirect":
get:
parameters:
- name: url
in: query
schema:
type: string
- name: pid
in: query
schema:
type: string
responses:
'302':
description: 302 response
headers:
Cache-Control:
schema:
type: string
Set-Cookie:
schema:
type: string
Content-Type:
schema:
type: string
Location:
schema:
type: string
x-amazon-apigateway-integration:
responses:
default:
statusCode: '302'
responseParameters:
method.response.header.Cache-Control: "'no-store, no-cache, must-revalidate'"
method.response.header.Set-Cookie: "''"
method.response.header.Content-Type: "'text/html'"
method.response.header.Location: "''"
responseTemplates:
application/json: >
#*
Velocity (a Java-based template engine) is natively supported by AWS API Gateway
*#
#set($domain = ".example.com")
#set($redirectUrl = $input.params("url"))
#if($redirectUrl != "")
#set($redirectUrl = $util.urlDecode($redirectUrl))
#else
#set($defaultFallbackUrl = "https://www$domain")
#set($redirectUrl = $defaultFallbackUrl)
#end
#set($context.responseOverride.header.Location = $redirectUrl)
#set($trackingCookieValue = $input.params("pid"))
#if($trackingCookieValue != "")
#set($trackingCookieName = "affiliate_partner_id")
#set($maxAge = 60 * 60 * 24 * 30)
#set($context.responseOverride.header.Set-Cookie = "$trackingCookieName=$trackingCookieValue; Max-Age=$maxAge; path=/; domain=$domain")
#end
requestTemplates:
application/json: '{"statusCode":200}'
passthroughBehavior: when_no_templates
type: mock
Appendix: if you need to deploy the API Gateway mock integration via pure CloudFormation, here is my tricky solution:
# Reference: https://cloudkatha.com/api-gateway-custom-domain-using-cloudformation/
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Demo: how to deploy API Gateway via pure CloudFormation'
Resources:
ApiGatewayRestApi:
Type: AWS::ApiGateway::RestApi
Properties:
Body: <% Content of API Gateway OpenAPI YAML %>
ApiGatewayStage:
Type: AWS::ApiGateway::Stage
Properties:
DeploymentId: !Ref ApiGatewayDeployment__CUSTOM_FILE_HASH_PLACEHOLDER__
RestApiId: !Ref ApiGatewayRestApi
StageName: !Ref Env
# ⬇️ Solution B of https://medium.com/@rokaso/aws-cloudformation-terraform-not-deploying-your-api-gateway-changes-cd87d30850cc (Solution C does not work)
ApiGatewayDeployment__CUSTOM_FILE_HASH_PLACEHOLDER__:
Type: AWS::ApiGateway::Deployment
Properties:
RestApiId: !Ref ApiGatewayRestApi
ApiGatewayBasePathMapping:
Type: AWS::ApiGateway::BasePathMapping
Properties:
BasePath: ""
DomainName: <% Your domain name %>
RestApiId: !Ref ApiGatewayRestApi
Stage: !Ref ApiGatewayStage