Search code examples
javafunctionaws-lambdamicronautpoc

Running micronaut serverless locally


I'm trying to create an AWS Lambda function with micronaut using functions i.e. I created my poc project with:

mn create-function-app --build=maven --jdk=11 micronaut-test

I can build and deploy it to AWS very easily but I wonder if there is a way to run it locally so I can quickly test changes in the same way you can run a regular micronaut app with

mvn mn:run

Right now is just the sample app, reformulating my question; Can I trigger the execute method in BookRequestHandler without uploading it to AWS?

Thanks in advance.


Solution

  • Maven profiles can be used to select the runtime (in this expample uses netty) and the main class:

        <profiles>
            <profile>
                <id>local</id>
                <properties>
                    <exec.mainClass>micronaut.Application</exec.mainClass>
                    <micronaut.runtime>netty</micronaut.runtime>
                </properties>
                <dependencies>
                    <dependency>
                        <groupId>io.micronaut</groupId>
                        <artifactId>micronaut-http-server-netty</artifactId>
                        <scope>compile</scope>
                    </dependency>
                </dependencies>
            </profile>
        </profiles>
    

    Create the main class with a controller with a Post method that calls the function

    package micronaut;
    
    import io.micronaut.http.annotation.Body;
    import io.micronaut.http.annotation.Controller;
    import io.micronaut.http.annotation.Post;
    import io.micronaut.runtime.Micronaut;
    import micronaut.test.Book;
    import micronaut.test.BookRequestHandler;
    import micronaut.test.BookSaved;
    
    public class Application {
    
        public static void main(String[] args) {
            Micronaut.run(Application.class, args);
        }
    
        @Controller()
        public static class LambdaController {
    
            private static final BookRequestHandler handler = new BookRequestHandler();
    
            @Post
            public BookSaved execute(@Body Book book) {
                return handler.execute(book);
            }
        }
    }
    
    

    and run with

    mvnw mn:run -Plocal
    

    Now you can use

    curl --location --request POST 'http://localhost:8080/' \
    --header 'Content-Type: application/json' \
    --data-raw '{"name": "Test"}'
    

    returning

    {
        "name": "Test",
        "isbn": "2a163c3d-4bd6-444d-914d-58daf3e649b8"
    }
    

    This a bit hacky, to test your function you can see micronaut-test/src/test/java/micronaut/test/BookRequestHandlerTest.java class or see Testing Lambda Handlers official docs.

    Note: For applications created with mn create-app -f aws-lambda ... is not needed the <exec.mainClass> in pom.xml, and the Application.java is generated.