Building APIs with Cloud Run
If I want to build an API, I usually use Cloud Run. In Cloud Run, you run a container and in that container, you run a web server that handles a base URL in this format:
https://<service-name>-<hash>-<region>.a.run.app
You can then have the web server handle any path under that base URL such as:
https://<service-name>-<hash>-<region>.a.run.app/hello
https://<service-name>-<hash>-<region>.a.run.app/bye
Building APIs with Cloud Functions
In Cloud Functions, you only have access to a function (no web server) and that function can only handle the base path:
https://<region>-<project>.cloudfunctions.net/<function>
You cannot have additional paths under that base path. This is one task one function design of Cloud Functions.
Does this mean that you cannot use Cloud Functions to build APIs with multiple paths? Not necessarily.
Workarounds
Guillaume Blaquiere, our Cloud GDE, talked about a couple of workarounds in Python and Go on how to handle multiple paths in a Cloud Function:
- Use multiple paths in Cloud Functions, Python and Flask
- Hack: Use Cloud Functions as a webserver with Golang
If you want a simple solution within a single Cloud Function, these could work but they’re workarounds and somewhat going against the design of Cloud Functions.
API Gateway
A better approach is to use API Gateway. You let each Cloud Function handle single path and let API Gateway route sub-paths according to the rules you define:
You can check my cloud-functions-api repo for details on how to set this up but it involves 4 steps:
- Deploy 2 functions
helloWorld
andbyeWorld
. - Create an API.
- Create an API config using the OpenAPI spec to define which path goes to which function.
- Deploy the API config to a gateway.
The API config file, openapi2-functions.yaml, defines the paths as follows:
paths:
/hello:
get:
summary: Greet a user
operationId: hello
x-google-backend:
address: https://REGION-PROJECT_ID.cloudfunctions.net/helloWorld
responses:
'200':
description: A successful response
schema:
type: string
/bye:
get:
summary: Greet a user
operationId: bye
x-google-backend:
address: https://REGION-PROJECT_ID.cloudfunctions.net/byeWorld
responses:
'200':
description: A successful response
schema:
type: string
With this setup, you have beginnings of an API backed by 2 Cloud Functions and powered by the API Gateway:
# Test hello
curl https://greeter-gateway-5abbajef.ew.gateway.dev/hello
Hello, World
# Test bye
curl https://greeter-gateway-5abbajef.ew.gateway.dev/bye
Bye, World
Feel free to reach out to me on Twitter @meteatamel for any questions/feedback.