1. Introduction
Google Cloud Functions is an event-driven serverless compute platform. Cloud Functions allows you to write your code without worrying about provisioning resources or scaling to handle changing requirements.
There are two types of Cloud Functions:
- HTTP functions respond to HTTP requests.
- Background functions are triggered by events, like a message being published to Cloud Pub/Sub or a file being uploaded to Cloud Storage.
This codelab will walk you through creating your own Cloud Functions in C#. More specifically, you will deploy C# functions responding to HTTP and CloudEvents from various Google Cloud sources.
What you'll learn
- Functions Framework for .NET.
- How to write an HTTP Function.
- How to write a CloudEvent Function responding to Cloud Storage events.
- How to write a CloudEvent Function responding to Cloud Pub/Sub events.
- How to write a CloudEvent Function responding to any type of event.
2. Setup and Requirements
Self-paced environment setup
- Sign in to Cloud Console and create a new project or reuse an existing one. If you don't already have a Gmail or Google Workspace account, you must create one.
Remember the project ID, a unique name across all Google Cloud projects (the name above has already been taken and will not work for you, sorry!). It will be referred to later in this codelab as PROJECT_ID
.
- Next, you'll need to enable billing in Cloud Console in order to use Google Cloud resources.
Running through this codelab shouldn't cost much, if anything at all. Be sure to to follow any instructions in the "Cleaning up" section which advises you how to shut down resources so you don't incur billing beyond this tutorial. New users of Google Cloud are eligible for the $300 USD Free Trial program.
Start Cloud Shell
While Google Cloud can be operated remotely from your laptop, in this codelab you will be using Google Cloud Shell, a command line environment running in the Cloud.
From the GCP Console click the Cloud Shell icon on the top right toolbar:
It should only take a few moments to provision and connect to the environment. When it is finished, you should see something like this:
This virtual machine is loaded with all the development tools you'll need. It offers a persistent 5GB home directory, and runs on Google Cloud, greatly enhancing network performance and authentication. All of your work in this lab can be done with simply a browser.
3. Functions Framework for .NET
Functions Framework for .NET is an open source FaaS (Function as a Service) framework for writing portable .NET functions – brought to you by the Google Cloud Functions team.
The Functions Framework lets you write lightweight functions that run in many different environments, including:
- Google Cloud Functions
- Your local development machine
- Cloud Run and Cloud Run on GKE
- Knative-based environments
In this codelab, you will use Functions Framework for .NET and its templates to create and deploy Cloud Functions in C#.
Inside Cloud Shell, run the following command to install Cloud Functions templates for dotnet
:
dotnet new --install Google.Cloud.Functions.Templates
This installs 3 templates for dotnet
. Each template is available in C#, F# and VB (but you'll only use C# in this lab). You can verify that templates are installed by running:
dotnet new gcf Templates Short Name ----------------------------------------------------------------------- Google Cloud Functions CloudEvent Function gcf-event Google Cloud Functions CloudEvent Function (Untyped) gcf-untyped-event Google Cloud Functions HttpFunction gcf-http
4. HTTP Function
You will create and deploy an HTTP Function responding to HTTP requests.
Create an HTTP Function using the gcf-http
template:
mkdir HelloHttp cd HelloHttp dotnet new gcf-http
This creates a project and a Function.cs
file responding to HTTP requests. Change the function to log requests as well:
using Google.Cloud.Functions.Framework; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using System.Threading.Tasks; namespace HelloHttp { public class Function : IHttpFunction { private readonly ILogger _logger; public Function(ILogger<Function> logger) => _logger = logger; public async Task HandleAsync(HttpContext context) { _logger.LogInformation("Function received request"); await context.Response.WriteAsync("Hello, Functions Framework."); } } }
Deploy the function,using dotnet3
runtime and trigger-http
flag:
gcloud functions deploy hello-http-function \ --runtime dotnet3 \ --trigger-http \ --entry-point HelloHttp.Function \ --allow-unauthenticated
After a minute or two, you should see the Cloud Function deployed in Cloud Console:
You can trigger the function by sending an HTTP request with gcloud functions call
:
gcloud functions call hello-http-function executionId: tp5h7d6t2vpl result: Hello, Functions Framework.
5. CloudEvent Function - GCS
You will create and deploy a CloudEvent Function responding to Google Cloud Storage (GCS) events.
First, create a Cloud Storage bucket. This is the bucket you will listen events from later:
GOOGLE_CLOUD_PROJECT=$(gcloud config get-value core/project) BUCKET_NAME="cloud-functions-bucket-${GOOGLE_CLOUD_PROJECT}" gsutil mb gs://${BUCKET_NAME}
Create an CloudEvent Function using the gcf-event
template:
mkdir HelloGcs cd HelloGcs dotnet new gcf-event
This creates a project and a Function.cs
file responding to CloudEvent
requests. It also parses the data of CloudEvent
into StorageObjectData
. Change the function to use a logger instead:
using CloudNative.CloudEvents; using Google.Cloud.Functions.Framework; using Google.Events.Protobuf.Cloud.Storage.V1; using Microsoft.Extensions.Logging; using System.Threading; using System.Threading.Tasks; namespace HelloGcs { public class Function : ICloudEventFunction<StorageObjectData> { private readonly ILogger _logger; public Function(ILogger<Function> logger) => _logger = logger; public Task HandleAsync(CloudEvent cloudEvent, StorageObjectData data, CancellationToken cancellationToken) { _logger.LogInformation("Event: {event}", cloudEvent.Id); _logger.LogInformation("Event Type: {type}", cloudEvent.Type); _logger.LogInformation("Bucket: {bucket}", data.Bucket); _logger.LogInformation("File: {file}", data.Name); _logger.LogInformation("Metageneration: {metageneration}", data.Metageneration); _logger.LogInformation("Created: {created:s}", data.TimeCreated?.ToDateTimeOffset()); _logger.LogInformation("Updated: {updated:s}", data.Updated?.ToDateTimeOffset()); return Task.CompletedTask; } } }
Deploy the function, using the dotnet3
runtime and trigger-event, trigger-resource
flags:
gcloud functions deploy hello-gcs-function \ --runtime dotnet3 \ --entry-point HelloGcs.Function \ --trigger-event google.storage.object.finalize \ --trigger-resource ${BUCKET_NAME} \ --allow-unauthenticated
After a couple of minutes, the function should be visible in Cloud Console:
Trigger the function by uploading a file to the storage bucket:
echo "Hello from Storage" > random.txt gsutil cp random.txt gs://${BUCKET_NAME}
Verify that the function was triggered by reading the logs:
gcloud functions logs read hello-gcs-function
6. CloudEvent Function - Pub/Sub
You will create and deploy a CloudEvent Function responding to Cloud Pub/Sub events.
First, create a Cloud Pub/Sub topic that will emit events:
TOPIC_NAME=cloud-functions-topic gcloud pubsub topics create ${TOPIC_NAME}
Create an CloudEvent Function using the gcf-event
template:
mkdir HelloPubSub cd HelloPubSub dotnet new gcf-event
This creates a project and a Function.cs
file responding to CloudEvent
requests. It also parses the data of CloudEvent
into StorageObjectData
by default.
Change StorageObjectData
to MessagePublishedData
to parse Pub/Sub messages instead and also use a logger instead. In the end, your function should look like this:
using CloudNative.CloudEvents; using Google.Cloud.Functions.Framework; using Google.Events.Protobuf.Cloud.PubSub.V1; using Microsoft.Extensions.Logging; using System.Threading; using System.Threading.Tasks; namespace HelloPubSub { public class Function : ICloudEventFunction<MessagePublishedData> { private readonly ILogger _logger; public Function(ILogger<Function> logger) => _logger = logger; public Task HandleAsync(CloudEvent cloudEvent, MessagePublishedData data, CancellationToken cancellationToken) { string nameFromMessage = data.Message?.TextData; string name = string.IsNullOrEmpty(nameFromMessage) ? "world" : nameFromMessage; _logger.LogInformation("Hello {name}", name); return Task.CompletedTask; } } }
Deploy the function, using the dotnet3
runtime and trigger-topic
flag:
gcloud functions deploy hello-pubsub-function \ --runtime dotnet3 \ --entry-point HelloPubSub.Function \ --trigger-topic ${TOPIC_NAME} \ --allow-unauthenticated
After a couple of minutes, the function should be visible in Cloud Console:
Trigger the function by publishing a message to the topic:
gcloud pubsub topics publish ${TOPIC_NAME} --message="World"
Verify that the function was triggered by reading the logs:
gcloud functions logs read hello-pubsub-function
7. CloudEvent Function - Untyped
If you are experimenting with CloudEvents and don't yet have a payload data model you wish to commit to, or you want your function to be able to handle any Cloud Event, you can use an untyped CloudEvent function.
Create an CloudEvent Function using the gcf-untyped-event
template:
mkdir HelloUntyped cd HelloUntyped dotnet new gcf-untyped-event
This creates a project and a Function.cs
file responding to CloudEvent
requests without any attempt to parse the data of the CloudEvent
. Change the function to log some CloudEvent
details:
using CloudNative.CloudEvents; using Google.Cloud.Functions.Framework; using Microsoft.Extensions.Logging; using System.Threading; using System.Threading.Tasks; namespace HelloUntyped { public class Function : ICloudEventFunction { private readonly ILogger _logger; public Function(ILogger<Function> logger) => _logger = logger; public Task HandleAsync(CloudEvent cloudEvent, CancellationToken cancellationToken) { _logger.LogInformation("Event: {event}", cloudEvent.Id); _logger.LogInformation("Event Type: {type}", cloudEvent.Type); return Task.CompletedTask; } } }
Deploy the function, using the dotnet3
runtime and trigger-event
flag:
gcloud functions deploy hello-untyped-function \ --runtime dotnet3 \ --entry-point HelloUntyped.Function \ --trigger-event google.storage.object.finalize \ --trigger-resource ${BUCKET_NAME} \ --allow-unauthenticated
The function will trigger when a file is uploaded to a storage bucket.
After a couple of minutes, the function should be visible in Cloud Console:
Trigger the function by uploading a file to the storage bucket:
echo "Hello from Storage" > random.txt gsutil cp random.txt gs://${BUCKET_NAME}
Verify that the function was triggered by reading the logs:
gcloud functions logs read hello-untyped-function
8. Congratulations!
Congratulations for completing the codelab.
What we've covered
- Functions Framework for .NET.
- How to write an HTTP Cloud Function.
- How to write a CloudEvent Function responding to Cloud Storage events.
- How to write a CloudEvent Function responding to Cloud Pub/Sub events.
- How to write a CloudEvent Function responding to any type of event.