[{"data":1,"prerenderedAt":403},["ShallowReactive",2],{"content-svc-lambda-guides-effectively-running-java-on-serverless-hexagonal":3},{"markdown":4,"frontMatterAttributes":5,"bodyRaw":23,"menu":24,"menuType":394,"isCollapseableMenu":27,"nextDocItem":149,"previousDocItem":124,"contributorPaths":395,"contentName":402,"slug":148,"readingTime":120},"\u003Cp>Loose coupling is a key guiding principle\nwhen building complex systems to ensure good quality and agility in development\nfor faster development cycles and easier adaptability to change.\nSystems should be designed with evolutionary architecture for agility.\nIn the book \u003Ca href=\"https:\u002F\u002Flearning.oreilly.com\u002Flibrary\u002Fview\u002Fbuilding-evolutionary-architectures\u002F9781491986356\u002F\">Building Evolutionary Architectures\u003C\u002Fa>,\nthis architecture is defined as one that supports guided, incremental change across multiple dimensions.\u003C\u002Fp>\n\u003Cp>Hexagonal Architecture is a pattern to build modular systems that allows for various components of the system\nto evolve independently.\nThis architectural pattern allows for decoupling of domain logic from implementation details,\nsuch as infrastructure, protocols, etc.\u003C\u002Fp>\n\u003Cp>\u003Cimg src=\"\u002Fassets\u002Fexternal\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fassets\u002Fhexagonal.png\" alt=\"Hexagonal\">\u003C\u002Fp>\n\u003Col>\n\u003Cli>\u003Cp>\u003Cstrong>Primary actors:\u003C\u002Fstrong> Users of the system such as an API or UI call via HTTP, an event message, or a test script.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\u003Cp>\u003Cstrong>Primary adapters:\u003C\u002Fstrong> They are a way for the primary actors (1) to interact with the application, via the domain logic.\nThe domain logic also uses ports for interacting with secondary actors (5).\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\u003Cp>\u003Cstrong>Ports:\u003C\u002Fstrong> A design pattern for transforming one interface into another interface.\nThey wrap the logic for interacting with a primary or secondary actor.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\u003Cp>\u003Cstrong>Domain logic:\u003C\u002Fstrong> Represents the task that the application should perform,\nabstracting any interaction with the external world.\nAll the business logic should be encapsulated in this component.\u003C\u002Fp>\n\u003C\u002Fli>\n\u003Cli>\u003Cp>\u003Cstrong>Secondary adapters:\u003C\u002Fstrong> Used by the application,\nthese adapters are either a Repository (for example, a database) or a Recipient (such as a message queue).\u003C\u002Fp>\n\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Ch4>Java example\u003C\u002Fh4>\n\u003Cp>Let&#39;s take a\n\u003Ca href=\"https:\u002F\u002Fdocs.aws.amazon.com\u002Fprescriptive-guidance\u002Flatest\u002Fhexagonal-architectures\u002Fexamples.html#start-simple\">simple example\u003C\u002Fa>\nas shown in the perspective guidance for building a hexagonal architecture in Java.\u003C\u002Fp>\n\u003Cp>\u003Cimg src=\"\u002Fassets\u002Fexternal\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fassets\u002Fhexagonal_java_example.png\" alt=\"HexagonalJavaExample\">\u003C\u002Fp>\n\u003Cp>An Amazon API Gateway endpoint acts as the \u003Cstrong>primary actor\u003C\u002Fstrong> and invokes the Lambda function as its backend.\nThe Lambda function acts as the \u003Cstrong>primary adapter\u003C\u002Fstrong> that uses a \u003Cstrong>port\u003C\u002Fstrong> in order to use the underlying business logic \npresent in the \u003Cstrong>domain\u003C\u002Fstrong> to create a \u003Ccode>Unicorn\u003C\u002Fcode>. \nThe underlying domain is responsible for creating the unicorn that is abstracted away from the Lambda function via\nport.\u003C\u002Fp>\n\u003Cp>In this example, the Lambda function code would look like the following:\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Primary Adapter\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-java\">public class CreateUnicornFunction implements RequestHandler&lt;\n  APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent&gt; {\n  \n  private CreateUnicorn port;\n\n  @Override\n  public APIGatewayProxyResponseEvent handleRequest(\n    APIGatewayProxyRequestEvent event, \n    Context context\n  ) {\n    \u002F\u002F Step 1: Create newUnicorn object from event payload\n\n    \u002F\u002F Step 2: Call port with the newUnicorn object\n    Unicorn unicorn = port.createUnicorn(newUnicorn);\n\n    \u002F\u002F Step 3: Send response back\n  }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>\u003Cstrong>Ports\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>Now, let&#39;s look at the port.\n\u003Ccode>CreateUnicorn\u003C\u002Fcode> is an interface which will be implemented by a service that is part of the underlying domain logic.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-java\">public interface CreateUnicorn {\n   Unicorn createUnicorn(Unicorn unicorn);\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>The domain logic will also need another \u003Ccode>port\u003C\u002Fcode> to handle persistence.\nIn this case, to persist the new Unicorn in the database.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-java\">public interface UnicornDatabasePort {\n   Unicorn createUnicorn(Unicorn unicorn);\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>A secondary adapter (DynamoDB adapter in this case) has to implement the logic specifically to persist\nthe domain (\u003Ccode>Unicorn\u003C\u002Fcode>) to a DynamoDB database.\u003C\u002Fp>\n\u003Cp>It will be clear when we look at the domain logic next.\u003C\u002Fp>\n\u003Cp>\u003Cstrong>Domain logic\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>The core domain logic includes the structure of \u003Ccode>Unicorn\u003C\u002Fcode> and the \u003Ccode>UnicornService\u003C\u002Fcode> that holds the business logic.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-java\">public class Unicorn {\n  private String id;\n  private String name;\n  private String age;\n  private String size;\n  private String type;\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>Now, the service class \u003Ccode>UnicornService\u003C\u002Fcode> implements \u003Ccode>CreateUnicorn\u003C\u002Fcode> port and internally uses the\n\u003Ccode>UnicornDatabasePort\u003C\u002Fcode> to create unicorn.\nThe \u003Ccode>UnicornDatabasePort\u003C\u002Fcode> totally abstracts the underlying implementation of persistence.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-java\">public class UnicornService implements CreateUnicorn {\n  private UnicornDatabasePort dbPort;\n\n  @Overrides\n  public Unicorn createUnicorn(Unicorn unicorn) {\n    logger.info(&quot;Creating unicorn..&quot;);\n\n    unicorn.setId(UUID.randomUUID().toString());\n    unicorn.setName(this.formatName(unicorn.getName()));\n\n    return dbPort.createUnicorn(unicorn);\n  }\n\n  \u002F\u002F This mimics a business logic\n  private String formatName(String name) {\n    return !StringUtils.isBlank(name) ?\n      name.toUpperCase() : name;\n  }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>\u003Cstrong>Secondary Adapter\u003C\u002Fstrong>\u003C\u002Fp>\n\u003Cp>A secondary adapter implements the logic that is required and has been abstracted away from the core domain.\nIn this case, it is the logic behind persistence.\u003C\u002Fp>\n\u003Cpre>\u003Ccode class=\"language-java\">public class UnicornDynamoDBAdapter implements UnicornDatabasePort {\n  private DynamoDbAsyncClient dynamoDbClient;\n  private static final String UNICORN_TABLE = &quot;Unicorn&quot;;\n\n  public UnicornDynamoDBAdapter() {\n    AwsCredentialsProvider provider = DefaultCredentialsProvider.create();\n\n    SdkAsyncHttpClient sdkAsyncHttpClient = AwsCrtAsyncHttpClient.builder()\n      .maxConcurrency(20)\n      .build();\n\n    try {\n      this.dynamoDbClient = DynamoDbAsyncClient.builder()\n        .credentialsProvider(provider)\n        .httpClient(sdkAsyncHttpClient)\n        .build();\n\n      this.dynamoDbClient.describeEndpoints();\n    } catch (URISyntaxException e) {\n      throw new RuntimeException(e);\n    }\n  }\n\n  public Unicorn createUnicorn(Unicorn unicorn) {\n    Map&lt;String, AttributeValue&gt; itemAttributes = Map.of(\n      &quot;id&quot;, AttributeValue.builder().s(unicorn.getId()).build(),\n      &quot;type&quot;, AttributeValue.builder().s(unicorn.getType()).build(),\n      &quot;name&quot;, AttributeValue.builder().s(unicorn.getName()).build(),\n      &quot;age&quot;, AttributeValue.builder().s(unicorn.getAge()).build(),\n      &quot;size&quot;, AttributeValue.builder().s(unicorn.getSize()).build()\n    );\n\n    dynamoDbClient.putItem(\n      PutItemRequest.builder()\n        .tableName(UNICORN_TABLE)\n        .item(itemAttributes)\n        .build()\n    ).get();\n\n    return unicorn;\n  }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Cp>In the future, if the requirement demands to use Amazon RDS, then a new secondary adapter for\nRDS can be added and injected to the domain service via the \u003Ccode>UnicornDatabasePort\u003C\u002Fcode> port. \u003C\u002Fp>\n\u003Cp>This is not limited to just secondary adapters. \nYou can extend the simple example from above to look like below architecture. \nThe main goal is to keep the domain logic abstracted away from\ndifferent adapters by using necessary ports.\u003C\u002Fp>\n\u003Cp>\u003Cimg src=\"\u002Fassets\u002Fexternal\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fassets\u002Fhexagonal_extension.png\" alt=\"HexagonalExtension\">\u003C\u002Fp>\n\u003Cp>To learn more about Hexagonal Architecture, read this\n\u003Ca href=\"https:\u002F\u002Fdocs.aws.amazon.com\u002Fprescriptive-guidance\u002Flatest\u002Fhexagonal-architectures\u002Foverview.html\">guidance\u003C\u002Fa> and\n\u003Ca href=\"https:\u002F\u002Faws.amazon.com\u002Fblogs\u002Fcompute\u002Fdeveloping-evolutionary-architecture-with-aws-lambda\u002F\">blog\u003C\u002Fa>.\u003C\u002Fp>\n",{"title":6,"order":7,"authors":8,"youtubeVideoID":10,"resources":11},"Hexagonal Architecture",6,[9],"Vipan Kumar","kRFg6fkVChQ",[12,16,20],{"link":13,"text":14,"type":15},"https:\u002F\u002Fdocs.aws.amazon.com\u002Fprescriptive-guidance\u002Flatest\u002Fhexagonal-architectures\u002Fwelcome.html","Hexagonal architecture","guidance",{"link":17,"text":18,"type":19},"https:\u002F\u002Faws.amazon.com\u002Fblogs\u002Fcompute\u002Fdeveloping-portable-aws-lambda-functions\u002F","Portable Lambda functions","blog",{"link":21,"type":19,"text":22},"https:\u002F\u002Faws.amazon.com\u002Fblogs\u002Fcompute\u002Fdeveloping-evolutionary-architecture-with-aws-lambda\u002F","Building evolutionary architecture on AWS Lambda","Loose coupling is a key guiding principle\nwhen building complex systems to ensure good quality and agility in development\nfor faster development cycles and easier adaptability to change.\nSystems should be designed with evolutionary architecture for agility.\nIn the book [Building Evolutionary Architectures](https:\u002F\u002Flearning.oreilly.com\u002Flibrary\u002Fview\u002Fbuilding-evolutionary-architectures\u002F9781491986356\u002F),\nthis architecture is defined as one that supports guided, incremental change across multiple dimensions.\n\nHexagonal Architecture is a pattern to build modular systems that allows for various components of the system\nto evolve independently.\nThis architectural pattern allows for decoupling of domain logic from implementation details,\nsuch as infrastructure, protocols, etc.\n\n![Hexagonal](\u002Fassets\u002Fexternal\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fassets\u002Fhexagonal.png)\n\n1. **Primary actors:** Users of the system such as an API or UI call via HTTP, an event message, or a test script.\n\n2. **Primary adapters:** They are a way for the primary actors (1) to interact with the application, via the domain logic.\n   The domain logic also uses ports for interacting with secondary actors (5).\n\n3. **Ports:** A design pattern for transforming one interface into another interface.\n   They wrap the logic for interacting with a primary or secondary actor.\n\n4. **Domain logic:** Represents the task that the application should perform,\n   abstracting any interaction with the external world.\n   All the business logic should be encapsulated in this component.\n\n5. **Secondary adapters:** Used by the application,\n   these adapters are either a Repository (for example, a database) or a Recipient (such as a message queue).\n\n#### Java example\nLet's take a\n[simple example](https:\u002F\u002Fdocs.aws.amazon.com\u002Fprescriptive-guidance\u002Flatest\u002Fhexagonal-architectures\u002Fexamples.html#start-simple)\nas shown in the perspective guidance for building a hexagonal architecture in Java.\n\n![HexagonalJavaExample](\u002Fassets\u002Fexternal\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fassets\u002Fhexagonal_java_example.png)\n\nAn Amazon API Gateway endpoint acts as the **primary actor** and invokes the Lambda function as its backend.\nThe Lambda function acts as the **primary adapter** that uses a **port** in order to use the underlying business logic \npresent in the **domain** to create a `Unicorn`. \nThe underlying domain is responsible for creating the unicorn that is abstracted away from the Lambda function via\nport.\n\nIn this example, the Lambda function code would look like the following:\n\n**Primary Adapter**\n\n```java\npublic class CreateUnicornFunction implements RequestHandler\u003C\n  APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {\n  \n  private CreateUnicorn port;\n\n  @Override\n  public APIGatewayProxyResponseEvent handleRequest(\n    APIGatewayProxyRequestEvent event, \n    Context context\n  ) {\n    \u002F\u002F Step 1: Create newUnicorn object from event payload\n\n    \u002F\u002F Step 2: Call port with the newUnicorn object\n    Unicorn unicorn = port.createUnicorn(newUnicorn);\n\n    \u002F\u002F Step 3: Send response back\n  }\n}\n```\n\n**Ports**\n\nNow, let's look at the port.\n`CreateUnicorn` is an interface which will be implemented by a service that is part of the underlying domain logic.\n\n```java\npublic interface CreateUnicorn {\n   Unicorn createUnicorn(Unicorn unicorn);\n}\n```\n\nThe domain logic will also need another `port` to handle persistence.\nIn this case, to persist the new Unicorn in the database.\n\n```java\npublic interface UnicornDatabasePort {\n   Unicorn createUnicorn(Unicorn unicorn);\n}\n```\n\nA secondary adapter (DynamoDB adapter in this case) has to implement the logic specifically to persist\nthe domain (`Unicorn`) to a DynamoDB database.\n\nIt will be clear when we look at the domain logic next.\n\n**Domain logic**\n\nThe core domain logic includes the structure of `Unicorn` and the `UnicornService` that holds the business logic.\n\n```java\npublic class Unicorn {\n  private String id;\n  private String name;\n  private String age;\n  private String size;\n  private String type;\n}\n```\n\nNow, the service class `UnicornService` implements `CreateUnicorn` port and internally uses the\n`UnicornDatabasePort` to create unicorn.\nThe `UnicornDatabasePort` totally abstracts the underlying implementation of persistence.\n\n```java\npublic class UnicornService implements CreateUnicorn {\n  private UnicornDatabasePort dbPort;\n\n  @Overrides\n  public Unicorn createUnicorn(Unicorn unicorn) {\n    logger.info(\"Creating unicorn..\");\n\n    unicorn.setId(UUID.randomUUID().toString());\n    unicorn.setName(this.formatName(unicorn.getName()));\n\n    return dbPort.createUnicorn(unicorn);\n  }\n\n  \u002F\u002F This mimics a business logic\n  private String formatName(String name) {\n    return !StringUtils.isBlank(name) ?\n      name.toUpperCase() : name;\n  }\n}\n```\n\n**Secondary Adapter**\n\nA secondary adapter implements the logic that is required and has been abstracted away from the core domain.\nIn this case, it is the logic behind persistence.\n\n```java\npublic class UnicornDynamoDBAdapter implements UnicornDatabasePort {\n  private DynamoDbAsyncClient dynamoDbClient;\n  private static final String UNICORN_TABLE = \"Unicorn\";\n\n  public UnicornDynamoDBAdapter() {\n    AwsCredentialsProvider provider = DefaultCredentialsProvider.create();\n\n    SdkAsyncHttpClient sdkAsyncHttpClient = AwsCrtAsyncHttpClient.builder()\n      .maxConcurrency(20)\n      .build();\n\n    try {\n      this.dynamoDbClient = DynamoDbAsyncClient.builder()\n        .credentialsProvider(provider)\n        .httpClient(sdkAsyncHttpClient)\n        .build();\n\n      this.dynamoDbClient.describeEndpoints();\n    } catch (URISyntaxException e) {\n      throw new RuntimeException(e);\n    }\n  }\n\n  public Unicorn createUnicorn(Unicorn unicorn) {\n    Map\u003CString, AttributeValue> itemAttributes = Map.of(\n      \"id\", AttributeValue.builder().s(unicorn.getId()).build(),\n      \"type\", AttributeValue.builder().s(unicorn.getType()).build(),\n      \"name\", AttributeValue.builder().s(unicorn.getName()).build(),\n      \"age\", AttributeValue.builder().s(unicorn.getAge()).build(),\n      \"size\", AttributeValue.builder().s(unicorn.getSize()).build()\n    );\n\n    dynamoDbClient.putItem(\n      PutItemRequest.builder()\n        .tableName(UNICORN_TABLE)\n        .item(itemAttributes)\n        .build()\n    ).get();\n\n    return unicorn;\n  }\n}\n```\n\nIn the future, if the requirement demands to use Amazon RDS, then a new secondary adapter for\nRDS can be added and injected to the domain service via the `UnicornDatabasePort` port. \n\nThis is not limited to just secondary adapters. \nYou can extend the simple example from above to look like below architecture. \nThe main goal is to keep the domain logic abstracted away from\ndifferent adapters by using necessary ports.\n\n![HexagonalExtension](\u002Fassets\u002Fexternal\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fassets\u002Fhexagonal_extension.png)\n\nTo learn more about Hexagonal Architecture, read this\n[guidance](https:\u002F\u002Fdocs.aws.amazon.com\u002Fprescriptive-guidance\u002Flatest\u002Fhexagonal-architectures\u002Foverview.html) and\n[blog](https:\u002F\u002Faws.amazon.com\u002Fblogs\u002Fcompute\u002Fdeveloping-evolutionary-architecture-with-aws-lambda\u002F).\n",[25,46,72,189,242,299,315,354,376],{"title":26,"collapsible":27,"isCollapsed":28,"content":29},"Introduction",false,true,[30],{"title":31,"order":32,"authors":33,"callout":35,"prerequisite":39,"time":42,"path":43,"id":44,"link":45},"Getting Started",1,[34],"Dhiraj Mahapatro",{"title":36,"description":37,"link":38},"Watch this video","This Devoxx Belgium 2023 presentation shows effectively running Java on Serverless","https:\u002F\u002Fyoutu.be\u002Fu3tgOE8qFjI?t=5549",[40,41],"Understanding of Java","Understanding of AWS Lambda","2 min","1-introduction","1-introduction.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002F1-introduction",{"title":47,"collapsible":27,"isCollapsed":28,"content":48},"History",[49,57,64],{"title":50,"order":51,"authors":52,"time":53,"path":54,"id":55,"link":56},"Evolution of Java",3,[34],"1 min","history","history.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fhistory",{"title":58,"order":59,"authors":60,"time":42,"path":61,"id":62,"link":63},"Evolution of Compute",4,[34],"compute","compute.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fcompute",{"title":65,"order":66,"authors":67,"time":42,"path":69,"id":70,"link":71},"Challenges",5,[34,68],"Maximilian Schellhorn","challenge","challenge.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fchallenge",{"title":73,"collapsible":27,"isCollapsed":27,"content":74},"Best Practices",[75,91,101,107,124,140,149,165,179],{"title":76,"order":7,"youtubeVideoID":77,"authors":78,"callout":79,"resources":82,"time":87,"path":88,"id":89,"link":90},"Lambda Snapstart","ZbnAithBNYY",[9,34],{"title":36,"description":80,"link":81},"This serverless office hours session dives deeper into Lambda SnapStart.","https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=Y5b8_KToeDY",[83],{"link":84,"text":85,"type":86},"https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=IIKe2dx9Ag0","Spring IO (Barcelona)","video","8 min","snapstart","snapstart.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fsnapstart",{"title":92,"order":7,"authors":93,"callout":94,"time":53,"path":98,"id":99,"link":100},"Tiered Compilation",[9],{"title":95,"description":96,"link":97},"Read this blog","This AWS blog explains Tiered compilation in details","https:\u002F\u002Faws.amazon.com\u002Fblogs\u002Fcompute\u002Fincreasing-performance-of-java-aws-lambda-functions-using-tiered-compilation\u002F","tiered-compilation","tiered-compilation.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Ftiered-compilation",{"title":102,"order":7,"authors":103,"time":53,"path":104,"id":105,"link":106},"Utilize initialization phase",[34],"init-heavy-lifting","init-heavy-lifting.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Finit-heavy-lifting",{"title":108,"order":7,"authors":109,"youtubeVideoID":111,"resources":112,"time":120,"path":121,"id":122,"link":123},"Using RDS Proxy",[110,34],"Sonali Jena","ZQOqmMn_8jw",[113,117],{"link":114,"text":115,"type":116},"https:\u002F\u002Faws.amazon.com\u002Fgetting-started\u002Fhands-on\u002Fset-up-shared-database-connection-amazon-rds-proxy\u002F","Shared DB connections with RDS Proxy","user guide",{"link":118,"type":116,"text":119},"https:\u002F\u002Fdocs.aws.amazon.com\u002FAmazonRDS\u002Flatest\u002FAuroraUserGuide\u002Frds-proxy.html","RDS Proxy","4 min","rds-proxy","rds-proxy.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Frds-proxy",{"title":125,"order":7,"authors":126,"callout":127,"prerequisite":131,"resources":133,"time":42,"path":137,"id":138,"link":139},"Choice of HTTP Clients",[9,34],{"title":128,"description":129,"link":130},"Read this Blog","This blog explains how AWS CRT HTTP Client offers faster startup time and small memory footprint","https:\u002F\u002Faws.amazon.com\u002Fblogs\u002Fdeveloper\u002Fannouncing-availability-of-the-aws-crt-http-client-in-the-aws-sdk-for-java-2-x\u002F",[132],"Before moving on to HTTP clients, the first and foremost requirement to improve performance in Lambda functions is to upgrade from AWS SDK Java v1 to AWS SDK Java v2 as soon as possible. Version 2 of the AWS SDK was released in Nov 2018 with a lot of performance upgrades.",[134],{"link":135,"type":19,"text":136},"https:\u002F\u002Faws.amazon.com\u002Fblogs\u002Fdeveloper\u002Faws-sdk-for-java-2-x-released\u002F","AWS SDK for Java v2","http-clients","http-clients.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fhttp-clients",{"title":6,"order":7,"authors":141,"youtubeVideoID":10,"resources":142,"time":120,"path":146,"id":147,"link":148},[9],[143,144,145],{"link":13,"text":14,"type":15},{"link":17,"text":18,"type":19},{"link":21,"type":19,"text":22},"hexagonal","hexagonal.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fhexagonal",{"title":150,"order":7,"authors":151,"youtubeVideoID":153,"resources":154,"time":42,"path":162,"id":163,"link":164},"Powertools for AWS Lambda",[152],"Lavanya Tangutur","dH2GP6Lydj8",[155,159],{"link":156,"text":157,"type":158},"https:\u002F\u002Fgithub.com\u002Faws-powertools\u002Fpowertools-lambda-java","Powertools for AWS Lambda (Java)","github",{"link":160,"type":19,"text":161},"https:\u002F\u002Faws.amazon.com\u002Fblogs\u002Fopensource\u002Fsimplifying-serverless-best-practices-with-aws-lambda-powertools-java\u002F","Best practices with Powertools","powertools","powertools.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fpowertools",{"title":166,"order":7,"authors":167,"youtubeVideoID":168,"callout":169,"resources":173,"time":53,"path":176,"id":177,"link":178},"Lambda Power tuning ",[152,34],"z8wGSykEauI",{"title":170,"description":171,"link":172},"Watch the video","This video covers a variety of AWS Lambda performance and cost optimization techniques including use of Power tuning.","https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=z8wGSykEauI",[174,175],{"link":114,"text":115,"type":116},{"link":118,"type":116,"text":119},"powertuning","powertuning.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fpowertuning",{"title":180,"order":7,"authors":181,"resources":182,"time":42,"path":186,"id":187,"link":188},"Using Graviton2",[34],[183],{"link":184,"text":185,"type":19},"https:\u002F\u002Faws.amazon.com\u002Fblogs\u002Fcompute\u002Fmigrating-aws-lambda-functions-to-arm-based-aws-graviton2-processors\u002F","Using Arm-based Graviton2 processors","graviton","graviton.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fgraviton",{"title":190,"collapsible":27,"isCollapsed":28,"content":191},"Java frameworks",[192,207,216,232],{"title":193,"order":194,"authors":195,"resources":196,"time":42,"path":204,"id":205,"link":206},"Micronaut",7,[152,34],[197,201],{"link":198,"text":199,"type":200},"https:\u002F\u002Fgithub.com\u002Faws-samples\u002Fserverless-java-frameworks-samples\u002Ftree\u002Fmain","Serverless Java Frameworks","GitHub",{"link":202,"text":203,"type":200},"https:\u002F\u002Fgithub.com\u002Faws-samples\u002Fserverless-patterns\u002Ftree\u002Fmain\u002Fapigw-lambda-rds-snapstart","Micronaut with RDS","micronaut","micronaut.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fmicronaut",{"title":208,"order":194,"authors":209,"resources":210,"time":42,"path":213,"id":214,"link":215},"Quarkus",[152,34],[211],{"link":198,"text":212,"type":200},"Quarkus sample application","quarkus","quarkus.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fquarkus",{"title":217,"order":194,"authors":218,"resources":219,"time":120,"path":229,"id":230,"link":231},"Spring",[152,68],[220,221,225],{"link":198,"text":212,"type":200},{"link":222,"text":223,"type":224},"https:\u002F\u002Fcatalog.workshops.aws\u002Fjava-on-aws-lambda\u002Fen-US","Java on AWS Lambda","workshop",{"link":226,"text":227,"type":228},"https:\u002F\u002Faws.amazon.com\u002Fblogs\u002Fdevops\u002Fdeveloping-with-java-and-spring-boot-using-amazon-codewhisperer\u002F","Build Spring Boot using Amazon CodeWhisperer","Blog","springboot","springboot.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fspringboot",{"title":233,"order":194,"authors":234,"resources":235,"time":42,"path":239,"id":240,"link":241},"GraalVM Native Image",[152,34],[236,238],{"link":198,"text":237,"type":200},"GraalVM sample application",{"link":222,"text":223,"type":224},"graalvm","graalvm.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fgraalvm",{"title":243,"collapsible":27,"isCollapsed":28,"content":244},"Testing a Java application",[245,262,271,281,290],{"title":246,"order":247,"authors":248,"callout":250,"resources":254,"time":258,"path":259,"id":260,"link":261},"Testing Serverless",8,[249],"Lorenzo Micheli",{"title":251,"description":252,"link":253},"Read the Serverless testing guide","This guide dives deeper into Serverless testing","https:\u002F\u002Fserverlessland.com\u002Ftesting",[255],{"link":256,"text":257,"type":200},"https:\u002F\u002Fgithub.com\u002Faws-samples\u002Fserverless-test-samples\u002Ftree\u002Fmain\u002Fjava-test-samples","Serverless Java test samples","3 min","testing","testing.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Ftesting",{"title":263,"order":247,"authors":264,"callout":265,"resources":266,"time":120,"path":268,"id":269,"link":270},"Unit Testing",[249],{"title":251,"description":252,"link":253},[267],{"link":256,"text":257,"type":200},"unit","unit.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Funit",{"title":272,"order":247,"authors":273,"callout":274,"resources":275,"time":277,"path":278,"id":279,"link":280},"Integration Testing",[249,34],{"title":251,"description":252,"link":253},[276],{"link":256,"text":257,"type":200},"5 min","integration","integration.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fintegration",{"title":282,"order":247,"authors":283,"callout":284,"resources":285,"time":258,"path":287,"id":288,"link":289},"Functional Testing",[249,34],{"title":251,"description":252,"link":253},[286],{"link":256,"text":257,"type":200},"functional","functional.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Ffunctional",{"title":291,"order":247,"authors":292,"callout":293,"resources":294,"time":42,"path":296,"id":297,"link":298},"Load Testing",[34],{"title":251,"description":252,"link":253},[295],{"link":256,"text":257,"type":200},"load","load.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fload",{"title":300,"collapsible":27,"isCollapsed":28,"content":301},"Local Development",[302,309],{"title":303,"order":304,"authors":305,"time":53,"path":306,"id":307,"link":308},"IntelliJ",10,[34],"intellij","intellij.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fintellij",{"title":310,"order":304,"authors":311,"time":53,"path":312,"id":313,"link":314},"Visual Studio Code",[34],"vscode","vscode.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fvscode",{"title":316,"collapsible":27,"isCollapsed":28,"content":317},"Infrastructure as Code",[318,325,331,341],{"title":319,"order":320,"authors":321,"time":42,"path":322,"id":323,"link":324},"CloudFormation",9,[110],"cloudformation","cloudformation.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fcloudformation",{"title":326,"order":320,"authors":327,"time":277,"path":328,"id":329,"link":330},"AWS CDK",[110],"cdk","cdk.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fcdk",{"title":332,"order":320,"authors":333,"resources":334,"time":42,"path":338,"id":339,"link":340},"AWS SAM",[110],[335],{"link":336,"text":337,"type":19},"https:\u002F\u002Faws.amazon.com\u002Fblogs\u002Fcompute\u002Fbuilding-serverless-java-applications-with-the-aws-sam-cli\u002F","Java Serverless AWS SAM CLI","sam","sam.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fsam",{"title":342,"order":320,"authors":343,"resources":344,"time":42,"path":351,"id":352,"link":353},"Terraform",[34],[345,348],{"link":346,"type":200,"text":347},"https:\u002F\u002Fgithub.com\u002Faws-samples\u002Fserverless-patterns\u002Ftree\u002Fmain\u002Fapigw-lambda-snapstart-terraform","Java sample with Terraform",{"link":349,"text":350,"type":116},"https:\u002F\u002Fdocs.aws.amazon.com\u002Fserverless-application-model\u002Flatest\u002Fdeveloperguide\u002Fwhat-is-terraform-support.html","AWS SAM CLI Terraform support","terraform","terraform.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fterraform",{"title":355,"collapsible":27,"isCollapsed":28,"content":356},"Benchmarking",[357],{"title":358,"order":359,"youtubeVideoID":360,"authors":361,"resources":362,"time":53,"path":373,"id":374,"link":375},"Performance Benchmarking",11,"wmEIMWigXGc",[34],[363,365,367,370],{"link":364,"text":223,"type":224},"https:\u002F\u002Fcatalog.workshops.aws\u002Fjava-on-aws-lambda\u002Fen-US\u002F01-migration\u002F02-optimizations\u002Fbenchmark",{"link":198,"text":366,"type":200},"Benchmark: Micronaut, Quarkus, and SpringBoot",{"link":368,"text":369,"type":200},"https:\u002F\u002Fgithub.com\u002Faws-samples\u002Fserverless-graalvm-demo","GraalVM native image on AWS Lambda Benchmarking",{"link":371,"text":372,"type":200},"https:\u002F\u002Fgithub.com\u002Faws-samples\u002Fserverless-kotlin-demo","Benchmark Kotlin on Serverless","benchmark","benchmark.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fbenchmark",{"title":377,"collapsible":27,"isCollapsed":28,"content":378},"Migration",[379],{"title":380,"order":381,"authors":382,"youtubeVideoID":383,"resources":384,"time":53,"path":391,"id":392,"link":393},"Migration Guide",12,[34],"u3tgOE8qFjI",[385,389],{"link":386,"text":387,"type":388},"https:\u002F\u002Fserverlessland.com\u002Fcontent\u002Fservice\u002Flambda\u002Fpaved-path\u002Fjava-replatforming\u002Fintroduction","Java re-platforming guide","Guide",{"link":222,"text":223,"type":390},"Workshop","migration","migration.md","\u002Fcontent\u002Fservice\u002Flambda\u002Fguides\u002Feffectively-running-java-on-serverless\u002Fmigration","LIST",[396,397,398,399,400,401],"content\u002Fcontributors\u002Fdhiraj-mahapatro.json","content\u002Fcontributors\u002Fsonali-jena.json","content\u002Fcontributors\u002Flavanya-tangutur.json","content\u002Fcontributors\u002Fvipan-kumar.json","content\u002Fcontributors\u002Florenzo-micheli.json","content\u002Fcontributors\u002Fmaximilian-schellhorn.json","Effectively running Java on Serverless",1792578873525]