{"id":16284967,"url":"https://github.com/goodforgod/simple-awslambda","last_synced_at":"2025-04-09T00:07:14.614Z","repository":{"id":192279414,"uuid":"310836504","full_name":"GoodforGod/simple-awslambda","owner":"GoodforGod","description":"🧰 Fast, Lightweight and GraalVM optimized AWS Lambda runtime.","archived":false,"fork":false,"pushed_at":"2023-09-03T22:50:47.000Z","size":631,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-30T07:01:49.697Z","etag":null,"topics":["aws-lambda","framework","graalvm","java","lambda","native-image","runtime","serverless"],"latest_commit_sha":null,"homepage":"http://goodforgod.dev/simple-awslambda/","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GoodforGod.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2020-11-07T12:09:42.000Z","updated_at":"2023-09-18T00:24:03.000Z","dependencies_parsed_at":"2023-09-03T23:54:12.229Z","dependency_job_id":null,"html_url":"https://github.com/GoodforGod/simple-awslambda","commit_stats":null,"previous_names":["goodforgod/simple-awslambda"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoodforGod%2Fsimple-awslambda","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoodforGod%2Fsimple-awslambda/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoodforGod%2Fsimple-awslambda/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoodforGod%2Fsimple-awslambda/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GoodforGod","download_url":"https://codeload.github.com/GoodforGod/simple-awslambda/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247947860,"owners_count":21023066,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aws-lambda","framework","graalvm","java","lambda","native-image","runtime","serverless"],"created_at":"2024-10-10T19:21:44.553Z","updated_at":"2025-04-09T00:07:14.595Z","avatar_url":"https://github.com/GoodforGod.png","language":"Java","readme":"# Simple AWSLambda\n\n![GraalVM Enabled](https://img.shields.io/badge/GraalVM-Ready-orange?style=plastic)\n[![Minimum required Java version](https://img.shields.io/badge/Java-17%2B-blue?logo=openjdk)](https://openjdk.org/projects/jdk/17/)\n[![Maven Central](https://maven-badges.herokuapp.com/maven-central/io.goodforgod/simple-awslambda/badge.svg)](https://maven-badges.herokuapp.com/maven-central/io.goodforgod/simple-awslambda)\n[![GitHub Action](https://github.com/goodforgod/simple-awslambda/workflows/CI%20Master/badge.svg)](https://github.com/GoodforGod/simple-awslambda/actions?query=CI+Master)\n[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=GoodforGod_simple-awslambda\u0026metric=coverage)](https://sonarcloud.io/dashboard?id=GoodforGod_simple-awslambda)\n[![Maintainability Rating](https://sonarcloud.io/api/project_badges/measure?project=GoodforGod_simple-awslambda\u0026metric=sqale_rating)](https://sonarcloud.io/dashboard?id=GoodforGod_simple-awslambda)\n[![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=GoodforGod_simple-awslambda\u0026metric=ncloc)](https://sonarcloud.io/dashboard?id=GoodforGod_simple-awslambda)\n\nFast, Lightweight and GraalVM oriented AWS Lambda Runtime.\n\nSimple and efficient way to build Native Java Serverless executables for AWS Lambda.\n\n## Dependency :rocket:\n\n[**Gradle**](https://mvnrepository.com/artifact/io.goodforgod/simple-awslambda)\n```groovy\nimplementation \"io.goodforgod:simple-awslambda:1.0.0\"\n```\n\n[**Maven**](https://mvnrepository.com/artifact/io.goodforgod/simple-awslambda)\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.goodforgod\u003c/groupId\u003e\n    \u003cartifactId\u003esimple-awslambda\u003c/artifactId\u003e\n    \u003cversion\u003e1.0.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n## Getting Started\n\n### Examples\n\nHere is repository with many examples of [simple-awslambda](https://github.com/GoodforGod/simple-awslambda-examples) for hello-world, DynamoDB, AuroraDB, etc.\n\n### Guide how to deploy\n\nGuide to deploy consists of 5 steps:\n1) [Build](#build) *function.zip* artifact via *build.sh*\n2) Sign in [AWS Accounts](https://console.aws.amazon.com/)\n3) Create AWS Lambda function\n4) Upload *function.zip* artifact\n5) Test\n6) Done\n\n## Ecosystem\n\n*simple-awslambda* runtime provides different *modules* that form an ecosystem and solve crucial serverless problems like:\n- [Logging](https://github.com/GoodforGod/slf4j-simple-logger)\n- [HTTP Components](https://github.com/GoodforGod/http-common)\n- [GraalVM Hints](https://github.com/GoodforGod/graalvm-hint)\n- [Docker Image](https://github.com/GoodforGod/docker-amazonlinux-graalvm)\n- [Testing](#testing)\n\n### Logging\n\nAws Lambda Runtime uses [slf4j](https://github.com/qos-ch/slf4j) for logging and not *LambdaLogger* that AWS Context API provides.\n\nIt is recommended to use [slf4j-simple-logger](https://github.com/GoodforGod/slf4j-simple-logger) for logging,\nit is part of *simple-awslambda* ecosystem and was designed to be used in serverless environment, is GraalVM friendly and easy to use.\n\nYou can use any SLF4J compatible implementation if needed.\n\nLogging example:\n```java\nLogger logger = LoggerFactory.getLogger(getClass());\nlogger.debug(\"Some logging...\");\n```\n\n#### Configuration\n\n[slf4j-simple-logger](https://github.com/GoodforGod/slf4j-simple-logger) configuration can use environment variables,\n*simple-awslambda* refresh configuration and all env configured properties will be updated.\n\nGiven configuration:\n```properties\norg.slf4j.simpleLogger.defaultLogLevel=${AWS_LAMBDA_LOGGING_LEVEL}\n```\n\nEach invocation configuration will be refreshed with actual value for environment variable *AWS_LAMBDA_LOGGING_LEVEL*.\n\n### Native Hints\n\nNative image require special configurations to build and run native executables. \nMost used cases is reflection config for DTO serialization/deserialization.\n\nYou can use any approach you would like to generate such configs, but there is library\nthat provide [annotation based](https://github.com/GoodforGod/graalvm-hint) way to generate such configs,\nthis is easy, simple and solid solution for such configs.\n\nYou can also use [GraalVM Native Image agent](https://graalvm.github.io/native-build-tools/latest/gradle-plugin.html#agent-support), but its up to you how to include and generate such configs.\n\n### Serialization\n\nDefault *Converter* implementation that is used for JSON serialization/deserialization is [GSON](https://github.com/google/gson) due to being the most lightweight, simple and solid solution.\n\nRecord are also supported by providing custom TypeAdapter.\n\n#### Configuration\n\nYou can use property file to configure GSON, [check this documentation](https://github.com/GoodforGod/gson-configuration#properties-file) for more info.\n\n### Http Components\n\nContracts provide Developer Friendly HTTP based components via [this library](https://github.com/GoodforGod/http-common) that is well integrated into all components.\n\nRuntime provides *SimpleHttpClient* and other contracts to interact with HTTP.\n\n#### Reactive\n\nRuntime that is responsible for handling Event is Reactive by design and returns Publisher from Java API.\n\n### Entrypoint\n\nThere two runtime entrypoints available to extend:\n- *AbstractInputLambdaEntrypoint* - entrypoint for direct event that should be propagated for processing.\n- *AbstractBodyLambdaEntrypoint* - entrypoint for body events (like APIGatewayV2HTTPEvent, APIGatewayV2WebSocketEvent), this entrypoint extracts Body from response and pass it to RequestHandler directly.\n\nYou can also choose what *RequestHandler* will be used for event processing via AWS environment variable *_HANDLER*.\n\n#### Event Support\n\nRuntime encourage using of [this aws event library](https://github.com/GoodforGod/aws-lambda-java-events)\ncause this library is GSON/Jackson/etc compatible, easy to use, up-to-date, without any external dependencies.\n\nYou can check library documentation for more info.\n\nIf you really want, you can use official [AWS Event SDK library](https://github.com/aws/aws-lambda-java-libs/tree/master/aws-lambda-java-events), but you should keep in mind all downsides.\n\n### Build\n\nRuntime encourage users to build their lambdas in three steps:\n- Build JAR via Gradle\n- Build Native Executable via Docker\n- Extract Native Executable from Docker\n\nEach project this is build via this runtime should include Dockerfile and bootstrap file.\n\n\nHere is simple boostrap example:\n```\n#!/bin/sh\nset -euo pipefail\n./application -Djava.library.path=$(pwd)\n```\n\nHere is simple Dockerfile example:\n```dockerfile\nFROM goodforgod/amazonlinux-graalvm:22.1.0-java17-amd64\n\nADD build/libs/*all.jar build/libs/application.jar\n\nRUN native-image --no-fallback -classpath build/libs/application.jar\n\nADD bootstrap bootstrap\nRUN chmod +x bootstrap application\n\nRUN zip -j function.zip bootstrap application\n\nEXPOSE 8080\nENTRYPOINT [\"/home/application/application\"]\n```\n\n1) Build your lambda JAR:\n```shell\n./gradlew shadowJar\n```\n\n2) Build Native Executable:\n```shell\ndocker build -t your-lambda-name .\n```\n\n3) Extract Native Executable:\n```shell\ndocker run --rm --entrypoint cat your-lambda-name /home/application/function.zip \u003e build/function.zip\n```\n\nAll this can be package into a simple *build.sh* shell script:\n```shell\n#!/bin/bash\n\ngradlew shadowJar\ndocker build -t your-lambda-name .\ndocker run --rm --entrypoint cat your-lambda-name /home/application/function.zip \u003e build/function.zip\n```\n\n#### Docker Image\n\nRuntime encourage using [this docker image](https://github.com/GoodforGod/docker-amazonlinux-graalvm), but as always you are free to use any image or approaches to build native executable.\n\n### Testing\n\nRuntime provides mechanisms to easily test Lambdas, this can be done via *AwsLambdaAssertions*.\n\nGiven Lambda Entrypoint:\n```java\npublic class InputLambdaEntrypoint extends AbstractInputLambdaEntrypoint {\n\n    public static void main(String[] args) {\n        new InputLambdaEntrypoint().run(args);\n    }\n\n    @Override\n    protected Consumer\u003cSimpleRuntimeContext\u003e setupInRuntime() {\n        return context -\u003e context.registerBean(new HelloWorldLambda());\n    }\n}\n```\n\nGiven Request Handler:\n```java\npublic class HelloWorldLambda implements RequestHandler\u003cRequest, Response\u003e {\n\n    private final Logger logger = LoggerFactory.getLogger(getClass());\n\n    @Override\n    public Response handleRequest(Request request, Context context) {\n        logger.info(\"Processing User with name: {}\", request.name());\n        return new Response(UUID.randomUUID().toString(), \"Hello - \" + request.name());\n    }\n}\n```\n\nGiven DTOs:\n```java\n@ReflectionHint\npublic record Request(String name) {}\n\n@ReflectionHint\npublic record Response(String id, String message) {}\n```\n\nTesting for such Lambda will look like:\n```java\nclass InputEventHandlerTests extends Assertions {\n\n    @Test\n    void eventHandled() {\n        final Request request = new Request(\"Steeven King\");\n        final Response response = AwsLambdaAssertions.ofEntrypoint(new InputLambdaEntrypoint())\n                .inputJson(request)\n                .expectJson(Response.class);\n\n        assertEquals(\"Hello - Steeven King\", response.message());\n    }\n}\n```\n\n## Extensibility\n\nMost of the core components like Converter, SimpleHttpClient, RuntimeContext, etc can be replaced with your implementations\nand this extensibility is a valuable feature.\n\nYou can easily extend, replace and improve all components, all ecosystem is open sourced as well and all components are independent.\n\n### Micronaut\n\nThere is Micronaut module extension that allow to use [Micronaut](/simple-awslambda-micronaut) as DI and all its components as well.\n\n## License\n\nThis project licensed under the Apache License 2.0 - see the [LICENSE](LICENSE) file for details","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoodforgod%2Fsimple-awslambda","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgoodforgod%2Fsimple-awslambda","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoodforgod%2Fsimple-awslambda/lists"}