L'implémentation des fonctions Lambda en Java peut être fastidieuse. Si vous utilisez la fonction Spring Cloud, le framework semble absorber la complexité de cette zone d'une manière agréable. Alors, j'ai essayé de voir si c'était vraiment bien absorbé et j'ai pu l'écrire rapidement.
À propos, il existe de nombreux exemples de Spring Cloud Function qui ne sont pas intégrés au proxy, mais je n'ai pas pu trouver la version intégrée, alors j'espère que cela aidera à la considérer.
Créez un projet Maven comme celui ci-dessous.
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 devrait ressembler à ceci.
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>
Créez une classe qui fait `` SpringApplication.run '' comme une application Spring Boot normale.
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);
}
}
Alors, créez un gestionnaire d'événements pour Lambda.
Pour être honnête, je ne sais pas pourquoi cette classe est vide ...
Puisqu'il est placé sur le back-end d'API Gateway, définissez respectivement APIGatewayProxyRequestEvent`` et
APIGatewayProxyResponseEvent``` pour l'entrée et la sortie.
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> {
}
Enfin, créez une classe de logique métier.
``APIGatewayProxyRequestEventQuand
APIGatewayProxyResponseEvent```Les spécifications sontjavadocAllons vérifier.
Cependant, même si Spring Cloud Function est compatible avec plusieurs clouds, si vous utilisez une telle interface, il s'agira d'une implémentation entièrement spécifique à AWS.
Ne vous inquiétez pas de la gestion désordonnée de JSON dans le dernier 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;
}
}
#Code de test Vous pouvez écrire le code de test normalement.
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\"}");
}
}
#Déployer Il est difficile de télécharger manuellement sur S3 ou d'attendre la construction du pipeline, alors déployons-le sur Texto avec Serverless Framework car ce n'est pas une version officielle de l'application.
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("$")'
Lorsque vous déployez avec cela, l'API REST sera renvoyée correctement comme ceci!
$ curl -X GET https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/testapi?id=11111; echo
{"name":"Taro"}
#Conclusion Eh bien, je n'ai pas du tout profité du framework Spring, donc j'ai l'impression que c'est le même effort que lorsque j'ai créé un gestionnaire d'événements Lambda normal. Serait-il apprécié que nous puissions utiliser davantage les fonctionnalités du framework?
Cette fois, je comprends que si vous écrivez des fonctions Lambda en Java, il est plus facile de les implémenter à l'aide d'APIGatewayProxyRequestEvent, et il est plus facile de déployer Serverless Framework.
Recommended Posts