Building APIs with Cloud Functions and API Gateway

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:

My colleague Guillaume Laforge also talked about how to have multiple paths in Node.js/Express apps and Cloud Functions:

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:

  1. Deploy 2 functions helloWorld and byeWorld.
  2. Create an API.
  3. Create an API config using the OpenAPI spec to define which path goes to which function.
  4. 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.

Originally published at https://atamel.dev.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store