Micronaut Azure HTTP Functions

Learn how to create an Azure HTTP Function with the Micronaut framework

Authors: Sergio del Amo

Micronaut Version: 3.2.7

1. Getting Started

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

2. What you will need

To complete this guide, you will need the following:

  • Some time on your hands

  • A decent text editor or IDE

  • JDK 1.8 or greater installed with JAVA_HOME configured appropriately

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 App

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

mn create-app example.micronaut.micronautguide --features=azure-function --build=maven --lang=java
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.

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

If you use Micronaut Launch, select "Micronaut Application" as application type and add the azure-function feature.

4.1. Enable annotation Processing

If you use Java or Kotlin and IntelliJ IDEA, make sure to enable annotation processing.

annotationprocessorsintellij

5. Azure CLI

Install Azure CLI

Azure CLI is a set of commands used to create and manage Azure resources. The Azure CLI is available across Azure services and is designed to get you working quickly with Azure, with an emphasis on automation.

6. Azure Functions Core Tools

Azure Function Core Tools includes a version of the same runtime that powers Azure Functions runtime that you can run on your local development computer. It also provides commands to create functions, connect to Azure, and deploy function projects.

7. Function

The created application contains class which extends AzureHttpFunction

src/main/java/example/micronaut/Function.java
package example.micronaut;
import java.util.*;
import com.microsoft.azure.functions.annotation.*;
import com.microsoft.azure.functions.*;
import io.micronaut.azure.function.http.AzureHttpFunction;

/**
 * Azure Functions with HTTP Trigger.
 */
public class Function extends AzureHttpFunction {
    /**
     * This function listens at endpoint "/api/*". Two ways to invoke it using "curl" command in bash:
     * 1. curl -d "HTTP Body" {your host}/api/*&code={your function key}
     * 2. curl "{your host}/api/*?name=HTTP%20Query&code={your function key}"
     * Function Key is not needed when running locally, it is used to invoke function deployed to Azure.
     * More details: https://aka.ms/functions_authorization_keys
     */
    @FunctionName("ExampleTrigger")
    public HttpResponseMessage invoke(
            @HttpTrigger(
                name = "req",
                methods = {HttpMethod.GET, HttpMethod.POST},
                route = "{*route}",
                authLevel = AuthorizationLevel.ANONYMOUS)
                HttpRequestMessage<Optional<String>> request,
                final ExecutionContext context) {
        return super.route(request, context);
    }
}

When you write a Micronaut Azure HTTP function, you will write your application as you will normally do when developing outside of Azure functions. That it is to say, you will create routes with classes annotated with @Controller. The above class bridges both worlds. It adapts from an Azure to a Micronaut HTTP Request, and based on the route, it delegates to the appropriate Micronaut controller.

8. Controller

The generated application contains a Controller which exposes two routes (GET and POST):

src/main/java/example/micronaut/MicronautguideController.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("/micronautguide")
public class MicronautguideController {

    @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 class is defined as a controller with the @Controller annotation mapped to the path /micronautguide

  • The @Get annotation maps the index method to all requests that use an HTTP GET.

  • By default a Micronaut response uses application/json as Content-Type. index method returns a String not a JSON object. Because of that, we set the response content-type to text/plain with the @Produces annotation.

  • The @Post annotation maps the postMethod method to all requests that use an HTTP GET.

  • Annotate the class with @Introspected to generate BeanIntrospection metadata at compilation time. This information can be used, for example, to the render the POJO as JSON using Jackson without using reflection.

9. Tests

The generated application contains a test which shows how to write a Micronaut Azure HTTP Function tests.

src/test/java/example/micronaut/MicronautguideFunctionTest.java
package example.micronaut;
import com.microsoft.azure.functions.HttpStatus;
import io.micronaut.azure.function.http.HttpRequestMessageBuilder;
import io.micronaut.http.HttpMethod;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class MicronautguideFunctionTest {

    @Test
    public void testFunction() throws Exception {
        try (Function function = new Function()) {
            HttpRequestMessageBuilder.AzureHttpResponseMessage response =
                function.request(HttpMethod.GET, "/micronautguide")
                        .invoke();

            assertEquals(HttpStatus.OK, response.getStatus());
        }
    }
}
  • Instantiating the function starts the Micronaut application context.

10. Testing the Application

To run the tests:

./mvnw test

11. Running the Application

To run the application use the ./mvnw package azure-functions:run command which will start the application on port 8080.

You can invoke the GET route:

curl -i localhost:7071/api/micronautguide
HTTP/1.1 200 OK
Date: Sat, 08 May 2021 03:55:11 GMT
Content-Type: text/plain
Server: Kestrel
Transfer-Encoding: chunked

Example Response

or the POST route:

curl -i -d '{"name":"John Snow"}' -H "Content-Type: application/json" -X POST http://localhost:7071/api/micronautguide
HTTP/1.1 200 OK
Date: Sat, 08 May 2021 03:57:56 GMT
Content-Type: application/json
Server: Kestrel
Transfer-Encoding: chunked

{"returnMessage":"Hello John Snow, thank you for sending the message"}

12. Create Azure Function App

Create a Function App in the Microsoft Azure Portal. If you prefer, use the Azure CLI.

azure functions 1
azure functions 2
azure functions 3

12.1. Basics | Create Function App

Select:

  • Runtime stack: Java

  • Version: 11

  • Region Central US

azure functions 4

12.2. Hosting | Create Function App

azure functions 5

Select:

  • Operating System: Windows.

  • Plan type: Consumption.

12.3. Monitoring | Create Function App

Enable Application Insights.

azure functions 6

12.4. Tags | Create Function App

azure functions 7

12.5. Review & Create | Create Function App

azure functions 8

13. Deploy Azure Function App

Login to azure portal in your terminal.

az login

Run ./mvnw package azure-functions:deploy to deploy your Azure Function App.

If you visit https://testmicronaut.azurewebsites.net/ you will get an HTML page informing you that the function is up and running.

You can invoke the GET route:

curl -i https://testmicronaut.azurewebsites.net/api/micronautguide
HTTP/1.1 200 OK
...
..
.
Example Response

15. Help with the Micronaut Framework

Object Computing, Inc. (OCI) sponsored the creation of this Guide. A variety of consulting and support services are available.