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:

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:

API Gateway with Cloud Functions

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.


See also