Deploy an HTTP Function to Google Cloud Functions

Deploy a Micronaut application as an HTTP Function to Google Cloud Functions - a scalable pay-as-you-go functions-as-a-service (FaaS) to run your code with zero server management.

Authors: Sergio del Amo

Micronaut Version: 4.3.7

1. Getting Started

In this guide, we will create a Micronaut application written in Java.

You are going to deploy a Micronaut application as an HTTP Function to Google Cloud Functions.

Cloud Functions is a serverless execution environment for building and connecting cloud services. With Cloud Functions, you write simple, single-purpose functions that are attached to events emitted from your cloud infrastructure and services. Your function is triggered when an event being watched is fired.

2. What you will need

To complete this guide, you will need the following:

You need a Google Cloud Platform (GCP) account and a GCP project.

3. Solution

We recommend that you follow the instructions in the next sections and create the application step by step. However, you can go right to the completed example.

4. Writing the Application

4.1. Create application

Create an application using the Micronaut Command Line Interface or with Micronaut Launch.

mn create-app example.micronaut.micronautguide \
              --features=google-cloud-function \
              --build=gradle \
              --lang=java \
              --jdk=17
If you don’t specify the --build argument, Gradle is used as the build tool.
If you don’t specify the --lang argument, Java is used as the language.
If you don’t specify the --test argument, JUnit is used for Java and Kotlin, and Spock is used for Groovy.

The previous command creates a Micronaut application with the default package example.micronaut in a directory named micronautguide.

If you have an existing Micronaut application and want to add the functionality described here, you can view the dependency and configuration changes from the specified features and apply those changes to your application.

4.2. Runtime

By supplying the feature google-cloud-function to the CLI command create-app, the Micronaut runtime is set to google_function.

A higher-level concept of "runtimes" is included in the Micronaut Gradle plugin, which essentially allows the plugin to decide which server runtime to include in the dependencies of the application when building the application.

build.gradle
...
..
micronaut {
    runtime("google_function")
...
}

5. Entry Point

The entry point of your HTTP Cloud Function is io.micronaut.gcp.function.http.HttpFunction. This is a class provided by the Micronaut GCP Function HTTP dependency. This dependency allows developers to create applications triggered by HTTP requests with classes annotated like @Controller and @Get etc.

That is to say, developers code HTTP Server applications deployed to HTTP Cloud Functions the same way as if they were targeting a runtime such as Netty. Micronaut GCP abstracts the details of the Cloud Function runtime so that developers can focus on their code.

6. Code

The generated project contains a Controller:

src/main/java/example/micronaut/DefaultController.java
package example.micronaut;

import io.micronaut.http.annotation.*;
import io.micronaut.http.annotation.Produces;
import io.micronaut.http.MediaType;
import io.micronaut.core.annotation.Introspected;

@Controller("/default")
public class DefaultController {

    @Produces(MediaType.TEXT_PLAIN)
    @Get
    public String index() {
        return "Example Response";
    }

    @Post
    public SampleReturnMessage postMethod(@Body SampleInputMessage inputMessage){
      SampleReturnMessage retMessage = new SampleReturnMessage();
      retMessage.setReturnMessage("Hello " + inputMessage.getName() + ", thank you for sending the message");
      return retMessage;
    }
}

@Introspected
class SampleInputMessage{
    private String name;

    public SampleInputMessage() {
    }

    public SampleInputMessage(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

@Introspected
class SampleReturnMessage{
    private String returnMessage;
    public String getReturnMessage() {
        return returnMessage;
    }
    public void setReturnMessage(String returnMessage) {
        this.returnMessage = returnMessage;
    }
}

The previous snippet exposes two endpoints (a GET and a POST endpoint) in the /default path.

7. Run Functions Locally

To run the function locally:

./gradlew runFunction
curl -w "\n" localhost:8080/micronautguide
Example Response
Automatically add newline with curl -w "\n"

8. Google Cloud Platform

You need a Google Cloud Platform (GCP) account.

You need a GCP project:

gcp project

9. Google Cloud CLI

Install Google Cloud CLI.

Log in to your Google Cloud Platform:

gcloud auth login

Change your project:

gcloud config set project micronaut-guides

My Project ID is micronaut-guides. You can get the IDs of your projects by running the command gcloud projects list.

10. Deploy

Create an executable jar including all dependencies:

./gradlew shadowJar

Then cd into the build/libs directory (deployment has to be done from the location where the JAR lives):

cd build/libs

You need a single JAR. Delete every 'jar' except *.all-jar.

Now run:

gcloud functions deploy micronautguide \
    --entry-point io.micronaut.gcp.function.http.HttpFunction \
    --runtime java17 \
    --trigger-http

Choose unauthenticated access. You do not need authenticated access for this tutorial.

To obtain the trigger URL, do the following:

YOUR_HTTP_TRIGGER_URL=$(gcloud functions describe micronautguide \
    --format='value(httpsTrigger.url)')

You can then use this variable to test the function invocation:

curl -w "\n" $YOUR_HTTP_TRIGGER_URL/micronautguide
Example Response

11. Next Steps

Read more about:

12. Help with the Micronaut Framework

The Micronaut Foundation sponsored the creation of this Guide. A variety of consulting and support services are available.

13. License

All guides are released with an Apache license 2.0 license for the code and a Creative Commons Attribution 4.0 license for the writing and media (images…​).