GCP Cloud Functions & API Gateway
Complete Deployment Guide with Terminal Commands
Initial Setup
Basic Authentication &
Project Setup
# Authenticate with GCP
gcloud auth login
# List all projects
gcloud projects list
# Set the active project
gcloud config set project PROJECT_ID
gcloud auth login
# List all projects
gcloud projects list
# Set the active project
gcloud config set project PROJECT_ID
# Set environment variables for easier reference
export PROJECT_ID="your-project-id"
export REGION="us-central1"
# Verify variables are set
echo "Project ID: $PROJECT_ID"
echo "Region: $REGION"
export PROJECT_ID="your-project-id"
export REGION="us-central1"
# Verify variables are set
echo "Project ID: $PROJECT_ID"
echo "Region: $REGION"
Enable Required Services
Basic Enable GCP Services
# Enable all required services
gcloud services enable cloudfunctions.googleapis.com \
run.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com \
apigateway.googleapis.com \
servicemanagement.googleapis.com \
servicecontrol.googleapis.com \
logging.googleapis.com \
--project=$PROJECT_ID
gcloud services enable cloudfunctions.googleapis.com \
run.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com \
apigateway.googleapis.com \
servicemanagement.googleapis.com \
servicecontrol.googleapis.com \
logging.googleapis.com \
--project=$PROJECT_ID
Tip: You can
check which services are already enabled with:
gcloud services list --enabled --project=$PROJECT_ID
IAM Roles for Developers
Intermediate
Required IAM Roles
# List of roles needed for Cloud Functions and API Gateway
development:
# roles/apigateway.admin
# roles/cloudfunctions.admin
# roles/cloudfunctions.invoker
# roles/iam.serviceAccountUser
# roles/serviceusage.serviceUsageViewer
# roles/serviceusage.serviceUsageConsumer
# roles/logging.viewer
# roles/monitoring.viewer
# roles/serviceusage.serviceUsageAdmin
# roles/apigateway.admin
# roles/cloudfunctions.admin
# roles/cloudfunctions.invoker
# roles/iam.serviceAccountUser
# roles/serviceusage.serviceUsageViewer
# roles/serviceusage.serviceUsageConsumer
# roles/logging.viewer
# roles/monitoring.viewer
# roles/serviceusage.serviceUsageAdmin
# Grant a user the necessary roles
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="user:user@example.com" \
--role="roles/cloudfunctions.admin"
# Repeat for other required roles
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="user:user@example.com" \
--role="roles/cloudfunctions.admin"
# Repeat for other required roles
# Check IAM policy for a project
gcloud projects get-iam-policy $PROJECT_ID \
--flatten="bindings[].members" \
--format="table(bindings.role, bindings.members)"
gcloud projects get-iam-policy $PROJECT_ID \
--flatten="bindings[].members" \
--format="table(bindings.role, bindings.members)"
Deploy Cloud Functions
Intermediate Deploy
Cloud Functions
# Deploy a public HTTP function (no authentication)
gcloud functions deploy getHelloWorld \
--gen2 \
--runtime nodejs20 \
--trigger-http \
--region $REGION \
--allow-unauthenticated \
--source="./functions/getHelloWorld" \
--entry-point="getHelloWorld" \
--project="$PROJECT_ID"
gcloud functions deploy getHelloWorld \
--gen2 \
--runtime nodejs20 \
--trigger-http \
--region $REGION \
--allow-unauthenticated \
--source="./functions/getHelloWorld" \
--entry-point="getHelloWorld" \
--project="$PROJECT_ID"
# Deploy a private HTTP function (requires authentication)
gcloud functions deploy getUserData \
--gen2 \
--runtime nodejs20 \
--trigger-http \
--region $REGION \
--no-allow-unauthenticated \
--source="./functions/getUserData" \
--entry-point="getUserData" \
--project="$PROJECT_ID"
gcloud functions deploy getUserData \
--gen2 \
--runtime nodejs20 \
--trigger-http \
--region $REGION \
--no-allow-unauthenticated \
--source="./functions/getUserData" \
--entry-point="getUserData" \
--project="$PROJECT_ID"
Note: After
deployment, you'll get URLs like:
https://$REGION-$PROJECT_ID.cloudfunctions.net/getHelloWorldhttps://$REGION-$PROJECT_ID.cloudfunctions.net/getUserData
# List all deployed functions
gcloud functions list --region=$REGION --project=$PROJECT_ID
gcloud functions list --region=$REGION --project=$PROJECT_ID
Deploy API Gateway
Advanced API Gateway
Deployment
# Set environment variables for API Gateway
export PROJECT_ID="your-project-id"
export REGION="us-central1"
export GATEWAY_NAME="user-check-gateway"
export API_NAME="user-check-api"
export API_CONFIG="user-check-config"
export API_YAML="api-gateway.yaml"
export PROJECT_ID="your-project-id"
export REGION="us-central1"
export GATEWAY_NAME="user-check-gateway"
export API_NAME="user-check-api"
export API_CONFIG="user-check-config"
export API_YAML="api-gateway.yaml"
# Step 1: Create the API
gcloud api-gateway apis create "$API_NAME" --project="$PROJECT_ID"
# Step 2: Create API config (requires YAML file)
gcloud api-gateway api-configs create "$API_CONFIG" \
--api="$API_NAME" \
--openapi-spec="$API_YAML" \
--project="$PROJECT_ID"
# Step 3: Create the gateway
gcloud api-gateway gateways create "$GATEWAY_NAME" \
--api="$API_NAME" \
--api-config="$API_CONFIG" \
--location="$REGION" \
--project="$PROJECT_ID"
gcloud api-gateway apis create "$API_NAME" --project="$PROJECT_ID"
# Step 2: Create API config (requires YAML file)
gcloud api-gateway api-configs create "$API_CONFIG" \
--api="$API_NAME" \
--openapi-spec="$API_YAML" \
--project="$PROJECT_ID"
# Step 3: Create the gateway
gcloud api-gateway gateways create "$GATEWAY_NAME" \
--api="$API_NAME" \
--api-config="$API_CONFIG" \
--location="$REGION" \
--project="$PROJECT_ID"
# Get the Gateway URL
export GATEWAY_URL=$(gcloud api-gateway gateways describe "$GATEWAY_NAME" \
--location="$REGION" --project="$PROJECT_ID" \
--format="value(defaultHostname)")
echo "API Gateway is live at: https://$GATEWAY_URL"
export GATEWAY_URL=$(gcloud api-gateway gateways describe "$GATEWAY_NAME" \
--location="$REGION" --project="$PROJECT_ID" \
--format="value(defaultHostname)")
echo "API Gateway is live at: https://$GATEWAY_URL"
# List all API gateways
gcloud api-gateway gateways list --project=$PROJECT_ID --format="table(name, location)"
gcloud api-gateway gateways list --project=$PROJECT_ID --format="table(name, location)"
# Get API Gateway details
gcloud api-gateway gateways describe $GATEWAY_NAME \
--location=$REGION --project=$PROJECT_ID
gcloud api-gateway gateways describe $GATEWAY_NAME \
--location=$REGION --project=$PROJECT_ID
API Keys Management
Intermediate API
Keys
# Check if API key already exists
EXISTING_API_KEY_NAME=$(gcloud alpha services api-keys list \
--filter='displayName="helloWorld API Key"' \
--format="value(name)" | tail -n 1)
if [ -z "$EXISTING_API_KEY_NAME" ]; then
echo "Creating new API Key..."
# Create API Key
gcloud alpha services api-keys create \
--display-name="helloWorld API Key" \
--format="value(name)"
sleep 10
else
echo "Reusing existing API Key: $EXISTING_API_KEY_NAME"
fi
# Get the API key value
API_KEY=$(gcloud alpha services api-keys get-key-string "$EXISTING_API_KEY_NAME" \
--format="get(keyString)" 2>/dev/null)
echo "API Key: $API_KEY"
EXISTING_API_KEY_NAME=$(gcloud alpha services api-keys list \
--filter='displayName="helloWorld API Key"' \
--format="value(name)" | tail -n 1)
if [ -z "$EXISTING_API_KEY_NAME" ]; then
echo "Creating new API Key..."
# Create API Key
gcloud alpha services api-keys create \
--display-name="helloWorld API Key" \
--format="value(name)"
sleep 10
else
echo "Reusing existing API Key: $EXISTING_API_KEY_NAME"
fi
# Get the API key value
API_KEY=$(gcloud alpha services api-keys get-key-string "$EXISTING_API_KEY_NAME" \
--format="get(keyString)" 2>/dev/null)
echo "API Key: $API_KEY"
# Enable the gateway service for API key authentication
# First, get the managed service name
MANAGED_SERVICE=$(gcloud api-gateway apis describe "$API_NAME" \
--project="$PROJECT_ID" --format="value(managedService)")
# Enable the service
gcloud services enable "$MANAGED_SERVICE" --project="$PROJECT_ID"
# First, get the managed service name
MANAGED_SERVICE=$(gcloud api-gateway apis describe "$API_NAME" \
--project="$PROJECT_ID" --format="value(managedService)")
# Enable the service
gcloud services enable "$MANAGED_SERVICE" --project="$PROJECT_ID"
# List all API keys
gcloud alpha services api-keys list --format="table(name, displayName)"
gcloud alpha services api-keys list --format="table(name, displayName)"
# Restrict API key to specific gateway
gcloud alpha services api-keys update "$API_KEY_NAME" \
--api-target=apigateway.googleapis.com \
--allowed-urls="https://$GATEWAY_URL/*" \
--project="$PROJECT_ID"
gcloud alpha services api-keys update "$API_KEY_NAME" \
--api-target=apigateway.googleapis.com \
--allowed-urls="https://$GATEWAY_URL/*" \
--project="$PROJECT_ID"
Testing the Deployment
Basic Test Endpoints
# Test public endpoint (no API key needed)
curl -X GET "https://$GATEWAY_URL/get-hello"
# Test secure endpoint (API key required)
curl -X GET "https://$GATEWAY_URL/get-user-data" \
-H "x-api-key: $API_KEY"
# Test POST endpoint
curl -X POST "https://$GATEWAY_URL/post-submit-data" \
-H "Content-Type: application/json" \
-d '{"name": "John", "email": "john@example.com"}'
curl -X GET "https://$GATEWAY_URL/get-hello"
# Test secure endpoint (API key required)
curl -X GET "https://$GATEWAY_URL/get-user-data" \
-H "x-api-key: $API_KEY"
# Test POST endpoint
curl -X POST "https://$GATEWAY_URL/post-submit-data" \
-H "Content-Type: application/json" \
-d '{"name": "John", "email": "john@example.com"}'
# Test Cloud Function directly
curl -X GET "https://$REGION-$PROJECT_ID.cloudfunctions.net/getHelloWorld"
# Test authenticated function with identity token
curl -X GET \
-H "Authorization: bearer $(gcloud auth print-identity-token)" \
"https://$REGION-$PROJECT_ID.cloudfunctions.net/getUserData"
curl -X GET "https://$REGION-$PROJECT_ID.cloudfunctions.net/getHelloWorld"
# Test authenticated function with identity token
curl -X GET \
-H "Authorization: bearer $(gcloud auth print-identity-token)" \
"https://$REGION-$PROJECT_ID.cloudfunctions.net/getUserData"
Update & Versioning
Advanced Update API
Gateway
# Create a new API config version
NEW_API_CONFIG="user-check-gateway-config-v2"
gcloud api-gateway api-configs create "$NEW_API_CONFIG" \
--api="$API_NAME" \
--openapi-spec="$API_YAML" \
--project="$PROJECT_ID"
# Update the gateway to use the new config
gcloud api-gateway gateways update "$GATEWAY_NAME" \
--api="$API_NAME" \
--api-config="$NEW_API_CONFIG" \
--location="$REGION" \
--project="$PROJECT_ID"
NEW_API_CONFIG="user-check-gateway-config-v2"
gcloud api-gateway api-configs create "$NEW_API_CONFIG" \
--api="$API_NAME" \
--openapi-spec="$API_YAML" \
--project="$PROJECT_ID"
# Update the gateway to use the new config
gcloud api-gateway gateways update "$GATEWAY_NAME" \
--api="$API_NAME" \
--api-config="$NEW_API_CONFIG" \
--location="$REGION" \
--project="$PROJECT_ID"
# Rollback to previous version if needed
gcloud api-gateway gateways update "$GATEWAY_NAME" \
--api-config="previous-config-name" \
--location="$REGION" \
--project="$PROJECT_ID"
gcloud api-gateway gateways update "$GATEWAY_NAME" \
--api-config="previous-config-name" \
--location="$REGION" \
--project="$PROJECT_ID"
# List all API configs for an API
gcloud api-gateway api-configs list --api="$API_NAME" \
--project="$PROJECT_ID"
gcloud api-gateway api-configs list --api="$API_NAME" \
--project="$PROJECT_ID"
Delete Resources
Intermediate Cleanup
Resources
# Delete Cloud Function
gcloud functions delete FUNCTION_NAME \
--region=$REGION \
--project=$PROJECT_ID
gcloud functions delete FUNCTION_NAME \
--region=$REGION \
--project=$PROJECT_ID
# Delete API Gateway and related resources
gcloud api-gateway gateways delete "$GATEWAY_NAME" \
--location="$REGION" \
--project="$PROJECT_ID"
gcloud api-gateway api-configs delete "$API_CONFIG" \
--api="$API_NAME" \
--project="$PROJECT_ID"
gcloud api-gateway apis delete "$API_NAME" \
--project="$PROJECT_ID"
gcloud api-gateway gateways delete "$GATEWAY_NAME" \
--location="$REGION" \
--project="$PROJECT_ID"
gcloud api-gateway api-configs delete "$API_CONFIG" \
--api="$API_NAME" \
--project="$PROJECT_ID"
gcloud api-gateway apis delete "$API_NAME" \
--project="$PROJECT_ID"
# Delete API Key
gcloud alpha services api-keys delete "API_KEY_NAME"
gcloud alpha services api-keys delete "API_KEY_NAME"
Troubleshooting
Advanced Common Issues &
Solutions
# Check API Gateway status
gcloud api-gateway gateways describe "$GATEWAY_NAME" \
--location="$REGION" \
--project="$PROJECT_ID"
# Check API configs
gcloud api-gateway api-configs list \
--api="$API_NAME" \
--project="$PROJECT_ID"
# Check Cloud Function logs
gcloud functions logs read FUNCTION_NAME \
--region=$REGION \
--project=$PROJECT_ID
gcloud api-gateway gateways describe "$GATEWAY_NAME" \
--location="$REGION" \
--project="$PROJECT_ID"
# Check API configs
gcloud api-gateway api-configs list \
--api="$API_NAME" \
--project="$PROJECT_ID"
# Check Cloud Function logs
gcloud functions logs read FUNCTION_NAME \
--region=$REGION \
--project=$PROJECT_ID
Common
Issues:
- API Gateway returns 404: Check if the managed service is enabled
- Authentication errors: Verify API key is correctly configured and restricted
- CORS issues: Configure CORS in your Cloud Function code
- Permission errors: Verify IAM roles are properly assigned
# Check if API Gateway service is enabled
gcloud services list --enabled --filter="apigateway" \
--project="$PROJECT_ID"
gcloud services list --enabled --filter="apigateway" \
--project="$PROJECT_ID"
Swagger Configuration
Advanced Swagger/OpenAPI
Specification
# Example Swagger configuration for API Gateway
swagger: "2.0"
info:
title: User Check API Gateway
version: "1.0.0"
schemes:
- https
paths:
/get-hello:
get:
summary: Public GET Endpoint
operationId: getUserInfo
x-google-backend:
address: https://us-central1-learning-cloud-450805.cloudfunctions.net/getHelloWorld
protocol: h2
responses:
"200":
description: "Successful GET request"
/get-user-data:
get:
summary: Secure GET Endpoint (Requires API Key)
operationId: getUserData
x-google-backend:
address: https://us-central1-learning-cloud-450805.cloudfunctions.net/getUserData
protocol: h2
security:
- api_key: []
responses:
"200":
description: "Successful authenticated request"
securityDefinitions:
api_key:
type: apiKey
name: x-api-key
in: header
swagger: "2.0"
info:
title: User Check API Gateway
version: "1.0.0"
schemes:
- https
paths:
/get-hello:
get:
summary: Public GET Endpoint
operationId: getUserInfo
x-google-backend:
address: https://us-central1-learning-cloud-450805.cloudfunctions.net/getHelloWorld
protocol: h2
responses:
"200":
description: "Successful GET request"
/get-user-data:
get:
summary: Secure GET Endpoint (Requires API Key)
operationId: getUserData
x-google-backend:
address: https://us-central1-learning-cloud-450805.cloudfunctions.net/getUserData
protocol: h2
security:
- api_key: []
responses:
"200":
description: "Successful authenticated request"
securityDefinitions:
api_key:
type: apiKey
name: x-api-key
in: header
# Example Swagger configuration for API Gateway
swagger: "2.0"
info:
title: User Check API Gateway
version: "1.0.0"
schemes:
- https
paths:
/get-hello:
get:
summary: Public GET Endpoint
operationId: getUserInfo
x-google-backend:
address: https://us-central1-learning-cloud-450805.cloudfunctions.net/getHelloWorld
protocol: h2
responses:
"200":
description: "Successful GET request"
/get-user-data:
get:
summary: Secure GET Endpoint (Requires API Key)
operationId: getUserData
x-google-backend:
address: https://us-central1-learning-cloud-450805.cloudfunctions.net/getUserData
protocol: h2
security:
- api_key: []
responses:
"200":
description: "Successful authenticated request"
securityDefinitions:
api_key:
type: apiKey
name: x-api-key
in: header
swagger: "2.0"
info:
title: User Check API Gateway
version: "1.0.0"
schemes:
- https
paths:
/get-hello:
get:
summary: Public GET Endpoint
operationId: getUserInfo
x-google-backend:
address: https://us-central1-learning-cloud-450805.cloudfunctions.net/getHelloWorld
protocol: h2
responses:
"200":
description: "Successful GET request"
/get-user-data:
get:
summary: Secure GET Endpoint (Requires API Key)
operationId: getUserData
x-google-backend:
address: https://us-central1-learning-cloud-450805.cloudfunctions.net/getUserData
protocol: h2
security:
- api_key: []
responses:
"200":
description: "Successful authenticated request"
securityDefinitions:
api_key:
type: apiKey
name: x-api-key
in: header
# Advanced Swagger configuration for API Gateway
swagger: "2.0"
info:
title: Advanced User Check API Gateway
description: Fully advanced Swagger config with API key, OAuth2, JWT, quota, and CORS
version: "1.0.0"
host: example-api.gateway.dev
schemes:
- https
basePath: /
consumes:
- application/json
produces:
- application/json
x-google-endpoints:
- name: example-api.gateway.dev
allowCors: true
paths:
/get-hello:
get:
summary: Public GET Endpoint
description: Simple hello endpoint without auth
operationId: getUserInfo
x-google-backend:
address: https://us-central1-learning-cloud-450805.cloudfunctions.net/getHelloWorld
protocol: h2
deadline: 15.0
path_translation: APPEND_PATH_TO_ADDRESS
responses:
"200":
description: Successful GET request
/get-user-data:
get:
summary: Secure GET Endpoint (Requires API Key)
operationId: getUserData
x-google-backend:
address: https://us-central1-learning-cloud-450805.cloudfunctions.net/getUserData
protocol: h2
deadline: 20.0
security:
- api_key: []
responses:
"200":
description: Successful authenticated request
"401":
description: Unauthorized
/get-user-oauth:
get:
summary: OAuth2 Secured Endpoint
operationId: getUserOAuth
x-google-backend:
address: https://us-central1-learning-cloud-450805.cloudfunctions.net/getUserOAuth
security:
- google_id_token: []
- firebase: []
responses:
"200":
description: Authenticated via OAuth2 / JWT
"403":
description: Forbidden
securityDefinitions:
api_key:
type: apiKey
name: x-api-key
in: header
google_id_token:
type: oauth2
authorizationUrl: ""
flow: implicit
x-google-issuer: https://accounts.google.com
x-google-jwks_uri: https://www.googleapis.com/oauth2/v3/certs
x-google-audiences: example-api-client-id.apps.googleusercontent.com
firebase:
type: oauth2
authorizationUrl: ""
flow: implicit
x-google-issuer: https://securetoken.google.com/my-firebase-project
x-google-jwks_uri: https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com
x-google-audiences: my-firebase-project
x-google-quota:
limits:
requests_per_minute:
name: per-minute
metric: serviceruntime.googleapis.com/api/request_count
unit: 1/min/{project}
values:
STANDARD: 100
requests_per_day:
name: per-day
metric: serviceruntime.googleapis.com/api/request_count
unit: 1/day/{project}
values:
STANDARD: 5000
x-google-backend:
deadline: 30.0
protocol: h2
path_translation: APPEND_PATH_TO_ADDRESS
x-google-allow:
- GET
- POST
- OPTIONS
x-google-allow-credentials: true
x-google-allow-headers:
- Authorization
- Content-Type
- x-api-key
x-google-allow-origin: "*"
x-google-custom-errors:
rules:
- error_code: 404
error_message: Custom Not Found Message
- error_code: 500
error_message: Something went wrong, please try again later.
swagger: "2.0"
info:
title: Advanced User Check API Gateway
description: Fully advanced Swagger config with API key, OAuth2, JWT, quota, and CORS
version: "1.0.0"
host: example-api.gateway.dev
schemes:
- https
basePath: /
consumes:
- application/json
produces:
- application/json
x-google-endpoints:
- name: example-api.gateway.dev
allowCors: true
paths:
/get-hello:
get:
summary: Public GET Endpoint
description: Simple hello endpoint without auth
operationId: getUserInfo
x-google-backend:
address: https://us-central1-learning-cloud-450805.cloudfunctions.net/getHelloWorld
protocol: h2
deadline: 15.0
path_translation: APPEND_PATH_TO_ADDRESS
responses:
"200":
description: Successful GET request
/get-user-data:
get:
summary: Secure GET Endpoint (Requires API Key)
operationId: getUserData
x-google-backend:
address: https://us-central1-learning-cloud-450805.cloudfunctions.net/getUserData
protocol: h2
deadline: 20.0
security:
- api_key: []
responses:
"200":
description: Successful authenticated request
"401":
description: Unauthorized
/get-user-oauth:
get:
summary: OAuth2 Secured Endpoint
operationId: getUserOAuth
x-google-backend:
address: https://us-central1-learning-cloud-450805.cloudfunctions.net/getUserOAuth
security:
- google_id_token: []
- firebase: []
responses:
"200":
description: Authenticated via OAuth2 / JWT
"403":
description: Forbidden
securityDefinitions:
api_key:
type: apiKey
name: x-api-key
in: header
google_id_token:
type: oauth2
authorizationUrl: ""
flow: implicit
x-google-issuer: https://accounts.google.com
x-google-jwks_uri: https://www.googleapis.com/oauth2/v3/certs
x-google-audiences: example-api-client-id.apps.googleusercontent.com
firebase:
type: oauth2
authorizationUrl: ""
flow: implicit
x-google-issuer: https://securetoken.google.com/my-firebase-project
x-google-jwks_uri: https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com
x-google-audiences: my-firebase-project
x-google-quota:
limits:
requests_per_minute:
name: per-minute
metric: serviceruntime.googleapis.com/api/request_count
unit: 1/min/{project}
values:
STANDARD: 100
requests_per_day:
name: per-day
metric: serviceruntime.googleapis.com/api/request_count
unit: 1/day/{project}
values:
STANDARD: 5000
x-google-backend:
deadline: 30.0
protocol: h2
path_translation: APPEND_PATH_TO_ADDRESS
x-google-allow:
- GET
- POST
- OPTIONS
x-google-allow-credentials: true
x-google-allow-headers:
- Authorization
- Content-Type
- x-api-key
x-google-allow-origin: "*"
x-google-custom-errors:
rules:
- error_code: 404
error_message: Custom Not Found Message
- error_code: 500
error_message: Something went wrong, please try again later.
# Full Advanced Swagger configuration for API Gateway
swagger: "2.0"
info:
title: Full Auth API Gateway
description: Includes public, API key, JWT, OAuth2, and custom key secured endpoints
version: "1.0.0"
host: example-api.gateway.dev
schemes:
- https
basePath: /
consumes:
- application/json
produces:
- application/json
x-google-endpoints:
- name: example-api.gateway.dev
allowCors: true
paths:
/auth/login:
post:
summary: User Login (Public)
description: Authenticate user and return JWT token
operationId: userLogin
x-google-backend:
address: https://us-central1-project.cloudfunctions.net/login
responses:
"200":
description: Login successful (returns JWT)
/auth/logout:
post:
summary: User Logout (Requires JWT)
operationId: userLogout
x-google-backend:
address: https://us-central1-project.cloudfunctions.net/logout
security:
- jwt_auth: []
responses:
"200":
description: Logout successful
/auth/register:
post:
summary: User Registration (Public)
operationId: userRegister
x-google-backend:
address: https://us-central1-project.cloudfunctions.net/register
responses:
"200":
description: Registration successful
/dashboard:
get:
summary: Dashboard (Requires API Key)
operationId: getDashboard
x-google-backend:
address: https://us-central1-project.cloudfunctions.net/dashboard
security:
- api_key: []
responses:
"200":
description: Dashboard data
/dashboard/course:
get:
summary: Dashboard Course (Requires OAuth2 or Custom Key)
operationId: getDashboardCourse
x-google-backend:
address: https://us-central1-project.cloudfunctions.net/course
security:
- google_oauth: []
- custom_key: []
responses:
"200":
description: Course data
securityDefinitions:
api_key:
type: apiKey
name: x-api-key
in: header
jwt_auth:
type: oauth2
flow: implicit
x-google-issuer: https://securetoken.google.com/my-project
x-google-jwks_uri: https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com
x-google-audiences: my-project
google_oauth:
type: oauth2
flow: implicit
x-google-issuer: https://accounts.google.com
x-google-jwks_uri: https://www.googleapis.com/oauth2/v3/certs
x-google-audiences: client-id.apps.googleusercontent.com
custom_key:
type: apiKey
name: x-custom-key
in: header
x-google-quota:
limits:
requests_per_minute:
name: per-minute
metric: serviceruntime.googleapis.com/api/request_count
unit: 1/min/{project}
values:
STANDARD: 100
x-google-allow:
- GET
- POST
- OPTIONS
x-google-allow-origin: "*"
x-google-allow-headers:
- Authorization
- Content-Type
- x-api-key
- x-custom-key
x-google-allow-credentials: true
swagger: "2.0"
info:
title: Full Auth API Gateway
description: Includes public, API key, JWT, OAuth2, and custom key secured endpoints
version: "1.0.0"
host: example-api.gateway.dev
schemes:
- https
basePath: /
consumes:
- application/json
produces:
- application/json
x-google-endpoints:
- name: example-api.gateway.dev
allowCors: true
paths:
/auth/login:
post:
summary: User Login (Public)
description: Authenticate user and return JWT token
operationId: userLogin
x-google-backend:
address: https://us-central1-project.cloudfunctions.net/login
responses:
"200":
description: Login successful (returns JWT)
/auth/logout:
post:
summary: User Logout (Requires JWT)
operationId: userLogout
x-google-backend:
address: https://us-central1-project.cloudfunctions.net/logout
security:
- jwt_auth: []
responses:
"200":
description: Logout successful
/auth/register:
post:
summary: User Registration (Public)
operationId: userRegister
x-google-backend:
address: https://us-central1-project.cloudfunctions.net/register
responses:
"200":
description: Registration successful
/dashboard:
get:
summary: Dashboard (Requires API Key)
operationId: getDashboard
x-google-backend:
address: https://us-central1-project.cloudfunctions.net/dashboard
security:
- api_key: []
responses:
"200":
description: Dashboard data
/dashboard/course:
get:
summary: Dashboard Course (Requires OAuth2 or Custom Key)
operationId: getDashboardCourse
x-google-backend:
address: https://us-central1-project.cloudfunctions.net/course
security:
- google_oauth: []
- custom_key: []
responses:
"200":
description: Course data
securityDefinitions:
api_key:
type: apiKey
name: x-api-key
in: header
jwt_auth:
type: oauth2
flow: implicit
x-google-issuer: https://securetoken.google.com/my-project
x-google-jwks_uri: https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com
x-google-audiences: my-project
google_oauth:
type: oauth2
flow: implicit
x-google-issuer: https://accounts.google.com
x-google-jwks_uri: https://www.googleapis.com/oauth2/v3/certs
x-google-audiences: client-id.apps.googleusercontent.com
custom_key:
type: apiKey
name: x-custom-key
in: header
x-google-quota:
limits:
requests_per_minute:
name: per-minute
metric: serviceruntime.googleapis.com/api/request_count
unit: 1/min/{project}
values:
STANDARD: 100
x-google-allow:
- GET
- POST
- OPTIONS
x-google-allow-origin: "*"
x-google-allow-headers:
- Authorization
- Content-Type
- x-api-key
- x-custom-key
x-google-allow-credentials: true
# Advanced Swagger 2.0 Example with Multiple Security Types
swagger: "2.0"
info:
title: Full Auth Example API Gateway
version: "1.0.0"
schemes:
- https
paths:
/register:
post:
summary: Public Register (no auth required)
operationId: registerUser
x-google-backend:
address: https://example.com/register
responses:
"200":
description: "User registered successfully"
/login:
post:
summary: Login with username/password to get JWT
operationId: loginUser
x-google-backend:
address: https://example.com/login
responses:
"200":
description: "Returns JWT token"
/logout:
post:
summary: Logout (requires JWT)
operationId: logoutUser
security:
- jwt_token: [] # depends on login
x-google-backend:
address: https://example.com/logout
responses:
"200":
description: "User logged out"
/dashboard:
get:
summary: Secure dashboard (JWT or OAuth2)
operationId: getDashboard
security:
- jwt_token: [] # OR
- oauth2: [read] # dashboard can be accessed via oauth2 scope
x-google-backend:
address: https://example.com/dashboard
responses:
"200":
description: "Dashboard data"
/dashboard/course:
get:
summary: Advanced - Requires BOTH JWT + Custom API Key
operationId: getCourses
security:
- jwt_token: []
- api_key: [] # multi-factor security
x-google-backend:
address: https://example.com/dashboard/course
responses:
"200":
description: "Course list"
securityDefinitions:
# 1. Custom API Key
api_key:
type: apiKey
name: x-api-key
in: header
# 2. JWT (Bearer Token)
jwt_token:
type: apiKey
name: Authorization
in: header
x-google-issuer: "https://securetoken.google.com/project-id"
x-google-jwks_uri: "https://www.googleapis.com/service_accounts/v1/jwk/project-id"
x-google-audiences: "project-id"
# 3. OAuth2
oauth2:
type: oauth2
authorizationUrl: "https://accounts.google.com/o/oauth2/auth"
flow: accessCode
tokenUrl: "https://oauth2.googleapis.com/token"
scopes:
read: "Read access to dashboard"
write: "Write access to dashboard"
swagger: "2.0"
info:
title: Full Auth Example API Gateway
version: "1.0.0"
schemes:
- https
paths:
/register:
post:
summary: Public Register (no auth required)
operationId: registerUser
x-google-backend:
address: https://example.com/register
responses:
"200":
description: "User registered successfully"
/login:
post:
summary: Login with username/password to get JWT
operationId: loginUser
x-google-backend:
address: https://example.com/login
responses:
"200":
description: "Returns JWT token"
/logout:
post:
summary: Logout (requires JWT)
operationId: logoutUser
security:
- jwt_token: [] # depends on login
x-google-backend:
address: https://example.com/logout
responses:
"200":
description: "User logged out"
/dashboard:
get:
summary: Secure dashboard (JWT or OAuth2)
operationId: getDashboard
security:
- jwt_token: [] # OR
- oauth2: [read] # dashboard can be accessed via oauth2 scope
x-google-backend:
address: https://example.com/dashboard
responses:
"200":
description: "Dashboard data"
/dashboard/course:
get:
summary: Advanced - Requires BOTH JWT + Custom API Key
operationId: getCourses
security:
- jwt_token: []
- api_key: [] # multi-factor security
x-google-backend:
address: https://example.com/dashboard/course
responses:
"200":
description: "Course list"
securityDefinitions:
# 1. Custom API Key
api_key:
type: apiKey
name: x-api-key
in: header
# 2. JWT (Bearer Token)
jwt_token:
type: apiKey
name: Authorization
in: header
x-google-issuer: "https://securetoken.google.com/project-id"
x-google-jwks_uri: "https://www.googleapis.com/service_accounts/v1/jwk/project-id"
x-google-audiences: "project-id"
# 3. OAuth2
oauth2:
type: oauth2
authorizationUrl: "https://accounts.google.com/o/oauth2/auth"
flow: accessCode
tokenUrl: "https://oauth2.googleapis.com/token"
scopes:
read: "Read access to dashboard"
write: "Write access to dashboard"
Tip: Use the
OpenAPI specification to define your API structure, security
requirements, and backend connections in a standardized format.
Multiple Gateways
Advanced Managing
Multiple Gateways
# Create multiple API gateways with different configurations
# Gateway 1
GATEWAY_1="gateway-1"
API_NAME_1="gateway-1-api"
API_CONFIG_1="gateway-1-config"
gcloud api-gateway apis create $API_NAME_1 --project=$PROJECT_ID
gcloud api-gateway api-configs create $API_CONFIG_1 \
--api=$API_NAME_1 \
--openapi-spec="gateway-1.yaml" \
--project=$PROJECT_ID
gcloud api-gateway gateways create $GATEWAY_1 \
--api=$API_NAME_1 \
--api-config=$API_CONFIG_1 \
--location=$REGION \
--project=$PROJECT_ID
# Gateway 2
GATEWAY_2="gateway-2"
API_NAME_2="gateway-2-api"
API_CONFIG_2="gateway-2-config"
gcloud api-gateway apis create $API_NAME_2 --project=$PROJECT_ID
gcloud api-gateway api-configs create $API_CONFIG_2 \
--api=$API_NAME_2 \
--openapi-spec="gateway-2.yaml" \
--project=$PROJECT_ID
gcloud api-gateway gateways create $GATEWAY_2 \
--api=$API_NAME_2 \
--api-config=$API_CONFIG_2 \
--location=$REGION \
--project=$PROJECT_ID
# Gateway 1
GATEWAY_1="gateway-1"
API_NAME_1="gateway-1-api"
API_CONFIG_1="gateway-1-config"
gcloud api-gateway apis create $API_NAME_1 --project=$PROJECT_ID
gcloud api-gateway api-configs create $API_CONFIG_1 \
--api=$API_NAME_1 \
--openapi-spec="gateway-1.yaml" \
--project=$PROJECT_ID
gcloud api-gateway gateways create $GATEWAY_1 \
--api=$API_NAME_1 \
--api-config=$API_CONFIG_1 \
--location=$REGION \
--project=$PROJECT_ID
# Gateway 2
GATEWAY_2="gateway-2"
API_NAME_2="gateway-2-api"
API_CONFIG_2="gateway-2-config"
gcloud api-gateway apis create $API_NAME_2 --project=$PROJECT_ID
gcloud api-gateway api-configs create $API_CONFIG_2 \
--api=$API_NAME_2 \
--openapi-spec="gateway-2.yaml" \
--project=$PROJECT_ID
gcloud api-gateway gateways create $GATEWAY_2 \
--api=$API_NAME_2 \
--api-config=$API_CONFIG_2 \
--location=$REGION \
--project=$PROJECT_ID
# Create API keys for different gateways
API_KEY_1_NAME="api-key-gateway-1"
API_KEY_1=$(gcloud alpha services api-keys create \
--display-name="$API_KEY_1_NAME" \
--format="value(name)" \
--project=$PROJECT_ID)
API_KEY_2_NAME="api-key-gateway-2"
API_KEY_2=$(gcloud alpha services api-keys create \
--display-name="$API_KEY_2_NAME" \
--format="value(name)" \
--project=$PROJECT_ID)
# Restrict each key to its specific gateway
GATEWAY_1_URL=$(gcloud api-gateway gateways describe $GATEWAY_1 \
--location=$REGION --project=$PROJECT_ID \
--format='value(defaultHostname)')
gcloud alpha services api-keys update "$API_KEY_1" \
--api-target=apigateway.googleapis.com \
--allowed-urls="https://$GATEWAY_1_URL/*" \
--project=$PROJECT_ID
API_KEY_1_NAME="api-key-gateway-1"
API_KEY_1=$(gcloud alpha services api-keys create \
--display-name="$API_KEY_1_NAME" \
--format="value(name)" \
--project=$PROJECT_ID)
API_KEY_2_NAME="api-key-gateway-2"
API_KEY_2=$(gcloud alpha services api-keys create \
--display-name="$API_KEY_2_NAME" \
--format="value(name)" \
--project=$PROJECT_ID)
# Restrict each key to its specific gateway
GATEWAY_1_URL=$(gcloud api-gateway gateways describe $GATEWAY_1 \
--location=$REGION --project=$PROJECT_ID \
--format='value(defaultHostname)')
gcloud alpha services api-keys update "$API_KEY_1" \
--api-target=apigateway.googleapis.com \
--allowed-urls="https://$GATEWAY_1_URL/*" \
--project=$PROJECT_ID
Pro Tips
-
Always use the
--dry-runflag when available to test commands without making changes - Use environment variables to avoid repetition and mistakes
- Enable detailed logging for debugging complex issues
- Regularly clean up unused resources to avoid unnecessary costs
- Use version control for your API Gateway configuration files
- Test your API Gateway configuration locally before deploying