Das Implementieren von Lambda-Funktionen in Java kann mühsam sein. Wenn Sie die Spring Cloud-Funktion verwenden, scheint das Framework die Komplexität dieses Bereichs auf nette Weise zu absorbieren. Also habe ich versucht zu sehen, ob es wirklich gut aufgenommen wurde und ich konnte es schnell schreiben.
Übrigens gibt es viele Beispiele für Spring Cloud Function, die nicht in den Proxy integriert sind, aber ich konnte die integrierte Version nicht finden, daher hoffe ich, dass es hilfreich ist, sie in Betracht zu ziehen.
Erstellen Sie ein Maven-Projekt wie das folgende.
SpringCloudFunctionTest
├── pom.xml
├── serverless.yml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── springcloudfunctiontest
│ │ ├── AWSLambdaHandler.java
│ │ ├── Hello.java
│ │ └── SpringCloudFunctionExampleApplication.java
│ └── resources
│ └── application.properties
└── test
└── java
└── com
└── springcloudfunctiontest
└── SpringCloudFunctionExampleApplicationTests.java
pom.xml sollte so aussehen.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.techprimers.serverless</groupId>
<artifactId>spring-cloud-function-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-cloud-function-test</name>
<description>Demo project for Spring Boot with Spring Cloud Function</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.SR2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-function-adapter-aws</artifactId>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-events</artifactId>
<version>2.0.2</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot.experimental</groupId>
<artifactId>spring-boot-thin-layout</artifactId>
<version>1.0.10.RELEASE</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>aws</shadedClassifierName>
</configuration>
</plugin>
</plugins>
</build>
</project>
Erstellen Sie eine Klasse, die SpringApplication.run wie eine normale Spring Boot-App ausführt.
SpringCloudFunctionExampleApplication.java
package com.springcloudfunctiontest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringCloudFunctionExampleApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudFunctionExampleApplication.class, args);
}
}
Erstellen Sie also einen Ereignishandler für Lambda. Um ehrlich zu sein, bin ich mir nicht sicher, warum diese Klasse leer ist ... Da es sich am Back-End des API-Gateways befindet, legen Sie für Eingabe und Ausgabe "APIGatewayProxyRequestEvent" und "APIGatewayProxyResponseEvent" fest.
AWSLambdaHandler.java
package com.springcloudfunctiontest;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
import org.springframework.cloud.function.adapter.aws.SpringBootRequestHandler;
public class AWSLambdaHandler extends SpringBootRequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
}
Erstellen Sie schließlich eine Klasse von Geschäftslogik.
``APIGatewayProxyRequestEventWann
APIGatewayProxyResponseEvent```Spezifikationen sindjavadocLass uns nachsehen.
Obwohl die Spring Cloud-Funktion mit mehreren Clouds kompatibel ist, handelt es sich bei Verwendung einer solchen Schnittstelle um eine vollständig AWS-spezifische Implementierung.
Machen Sie sich keine Sorgen über den unordentlichen Umgang mit dem JSON im letzten setBody.
Hello.java
package com.springcloudfunctiontest;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
import org.springframework.stereotype.Component;
import java.util.function.Function;
import java.util.Map;
@Component
public class Hello implements Function<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
@Override
public APIGatewayProxyResponseEvent apply(APIGatewayProxyRequestEvent input) {
Map<String, String> queryStringParameter = input.getQueryStringParameters();
String id = queryStringParameter.get("id");
String name = null;
if( id.equals("11111") ) {
name = "\"Taro\"";
} else {
name = "\"Nanashi\"";
}
APIGatewayProxyResponseEvent responseEvent = new APIGatewayProxyResponseEvent();
responseEvent.setStatusCode(200);
responseEvent.setBody("{\"name\":" + name + "}");
return responseEvent;
}
}
#Testcode Sie können Testcode normal schreiben.
SpringCloudFunctionExampleApplicationTests.java
package com.springcloudfunctiontest;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringCloudFunctionExampleApplicationTests {
@Test
public void HelloTest1() {
Hello hello = new Hello();
APIGatewayProxyRequestEvent request = new APIGatewayProxyRequestEvent();
Map<String,String> queryStringParameter = new HashMap<>();
queryStringParameter.put("id", "11111");
request.setQueryStringParameters(queryStringParameter);
APIGatewayProxyResponseEvent response = hello.apply(request);
assertThat(response.getBody()).isEqualTo("{\"name\":\"Taro\"}");
}
@Test
public void HelloTest2() {
Hello hello = new Hello();
APIGatewayProxyRequestEvent request = new APIGatewayProxyRequestEvent();
Map<String,String> queryStringParameter = new HashMap<>();
queryStringParameter.put("id", "22222");
request.setQueryStringParameters(queryStringParameter);
APIGatewayProxyResponseEvent response = hello.apply(request);
assertThat(response.getBody()).isEqualTo("{\"name\":\"Nanashi\"}");
}
}
#Bereitstellen Das manuelle Hochladen in S3 oder das Warten auf die Erstellung der Pipeline ist mühsam. Stellen Sie sie daher mit dem Serverless Framework in Texto bereit, da es sich nicht um eine offizielle Version der App handelt.
serverless.yml
service: test
provider:
name: aws
runtime: java8
timeout: 30
region: ap-northeast-1
package:
artifact: target/spring-cloud-function-test-0.0.1-SNAPSHOT-aws.jar
functions:
hello:
handler: org.springframework.cloud.function.adapter.aws.SpringBootStreamHandler
events:
- http:
path: testapi
method: get
integration: lambda-proxy
request:
template:
application/json: '$input.json("$")'
Wenn Sie damit bereitstellen, wird die REST-API wie folgt ordnungsgemäß zurückgegeben!
$ curl -X GET https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/testapi?id=11111; echo
{"name":"Taro"}
#Fazit Nun, ich habe das Spring-Framework überhaupt nicht genutzt, daher scheint es der gleiche Aufwand zu sein wie bei der Erstellung eines normalen Lambda-Ereignishandlers. Wäre es wünschenswert, wenn wir mehr Funktionen des Frameworks nutzen könnten?
Dieses Mal ist es meines Erachtens einfacher, die Implementierung mit APIGatewayProxyRequestEvent zu implementieren und das Serverless Framework einfacher bereitzustellen, wenn Sie Lambda-Funktionen in Java schreiben.
Recommended Posts