다양한 시그니쳐의 람다 작성 해보기
다양한 시그니처를 갖는 람다 핸들러를 작성해 보겠습니다.
각 메서드를 작성하면 테스트를 위해 template.yaml
의 핸들러 지정을 바꿔줍니다.
그리고 sam build
& sam local invoke --event events/events.json
을 사용하여 테스트를 진행합니다.
float → boolean
public boolean getNumber(float number) {
return number> 100000;
}
events.json
이벤트에 아무 숫자를 입력하자.
1234.4444
result
false
list → list
public List<Integer> getScores(List<String> names) {
Map<String, Integer> studentScores = new HashMap<String, Integer>();
studentScores.put("John", 90);
studentScores.put("Bob", 80);
studentScores.put("Ahmed", 100);
return names.stream()
.map(student-> studentScores.get(student))
.filter(it-> it != null)
.collect(Collectors.toList());
}
events.json
이벤트에 JSON Array를 정의하자.
["John", "Bob", "Ahmed"]
result
JSON Array가 반환되었다.
[90,80,100]
map<string, int> → void
public void saveEmployeeData(Map<String, Integer> empData) {
// do nothing
}
events.json
이벤트에 JSON Array를 정의하자.
{
"John": 1234,
"Bharath": 100000
}
result
자바 메서드 반환이 void이었더니 null
로 반환되었다.
null
void → map<string, list>
public Map<String, List<Integer>> getStudentScores() {
Map<String, List<Integer>> studentScores = new HashMap<String, List<Integer>>();
studentScores.put("John", Arrays.asList(80, 90, 100));
studentScores.put("Bob", Arrays.asList(10, 15, 22));
studentScores.put("Ahmed", Arrays.asList(33, 66, 99));
return studentScores;
}
events.json
이벤트에 아무것도 줄 필요 없다.
result
학생 이름을 key, 그들의 점수 리스트를 value로 하는 JSON 객체가 반환되었다.
{"Ahmed":[33,66,99],"Bob":[10,15,22],"John":[80,90,100]}
POJO → POJO
SNS, S3, API Gateway등이 람다를 호출하여 이벤트를 넘겨주면 특정 자바 POJO에 매핑된 형태로 람다 메서드에 도착합니다.
Hello World 템플릿은 API 게이트웨이가 쏴 주는 APIGatewayProxyRequestEvent
타입의 POJO를 받아내는 람다 메서드를 갖고 있었습니다.
아무튼 계속 진행...
public ClinicalData getClinical(Patient patient) {
System.out.println(patient);
ClinicalData clinicalData = new ClinicalData();
clinicalData.setBp("80/120");
clinicalData.setHeartRate("80");
return clinicalData;
}
pojos
public class Patient {
private String name;
private String ssn;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSsn() {
return ssn;
}
public void setSsn(String ssn) {
this.ssn = ssn;
}
@Override
public String toString() {
return "Patient{" +
"name='" + name + '\'' +
", ssn='" + ssn + '\'' +
'}';
}
}
public class ClinicalData {
private String bp;
private String heartRate;
public String getBp() {
return bp;
}
public void setBp(String bp) {
this.bp = bp;
}
public String getHeartRate() {
return heartRate;
}
public void setHeartRate(String heartRate) {
this.heartRate = heartRate;
}
}
events.json
Patient POJO 형식에 맞춘 JSON을 이벤트로 넣자.
{"name": "John", "ssn": "123444"}
result
ClinicalData POJO 형식에 맞춘 JSON이 반환되었다.
{"bp":"80/120","heartRate":"80"}
inpustream, outputstream → void
람다는 인풋 스트림에 반응할 수 있습니다. 그리고 아웃풋 스트림에 결과물을 써줄 수 있습니다.
스트림을 입력, 출력으로 사용하면 람다를 매우 동적으로 활용할 수 있습니다. 스트림 타입은 Map보다 훨씬 유연한 타입입니다.
람다 메서드의 이런 시그니쳐를 알아본 람다 서비스 및 람다 런타임은, 알아서 스트림을 형태로 인자를 주입하며, 스트림의 close()에 대해선 개발자가 신경 쓰지 않아도 됩니다.
* 테스트로는 영어 문자열을 입력 받아 소문자로 변환하여 되돌려 보낼 겁니다.
/**
* input 인풋 스트림에서 받은 데이터를 소문자 변환해서 output 아웃풋 스트림에 씁니다.
* 이 람다 메서드의 시그니쳐를 알아본 람다 서비스와 람다 런타임이 알아서 스트림을 생성하여 주입하며, close()에 대해 신경 쓰지 않아도 됩니다.
* 테스트 이벤트는 영어 문자열을 입력 받아 소문자로 변환하여 되돌려 보낼 겁니다.
* @param input 임의 형식을 갖는 데이터 스트림. POJO 매핑을 쓰는 람다와 비교하여 매우 유연한 입력 타입입니다.
* @param outputStream 임의 형식을 갖는 출력 스트림.
*/
public void getOutput(InputStream input, OutputStream outputStream) throws IOException {
int data;
while ((data = input.read()) != -1) {
outputStream.write(Character.toLowerCase(data));
}
}
events.json
임의 값을 입력하자. 인풋스트림으로 제공될 값이기 때문에 “”
로 묶는 작업도 하지 않았다.
Huh,,, I have no IDEA!
result
인풋 스트림(문자열 스트림)을 읽어서 그것을 소문자 변환한 문자열을 획득한다.
huh,,,, i have no idea!
Context 객체
람다 호출이 남긴 로그
END RequestId: 6c87a66c-31b5-4d0c-927b-c202c54126f7
REPORT RequestId: 6c87a66c-31b5-4d0c-927b-c202c54126f7
Init Duration: 0.18 ms
Duration: 322.19 ms
Billed Duration: 323 ms Memory Size: 256 MB
Max Memory Used: 256 MB
콘솔에서 람다 호출이 남긴 로그를 보면
- RequestID (→람다 요청은 매번 ID를 갖는다)
- Version (→ 람다 함수의 버젼)
- 실행 정보 및 과금 정보
이러한 유형의 정보들이 출력됩니다.
자바 런타임에서 이 값들이 람다 코어 라이브러리 [aws-lambda-java-core] 의 Context
객체에 담겨지는데
우리 람다에게 인자로 주입시켜서 각종 메타데이터를 뽑아 먹을 수 있습니다.
import com.amazonaws.services.lambda.runtime.Context;
public void getOutput(InputStream input, OutputStream outputStream, Context context) throws IOException {
System.out.println(context.getAwsRequestId());
System.out.println(context.getFunctionName());
System.out.println(context.getRemainingTimeInMillis());
System.out.println(context.getMemoryLimitInMB());
System.out.println(context.getLogGroupName());
int data;
while ((data = input.read()) != -1) {
outputStream.write(Character.toLowerCase(data));
}
}
result
인풋 스트림(문자열 스트림)을 읽어서 그것을 소문자 변환한 문자열을 획득한다.
cf8065ed-ff19-4e66-ae54-195d9c6b976b # aws request id
HelloWorldFunction # function name
2997 # remaining time in millis
256 # memory lmits (MB)
aws/lambda/HelloWorldFunction # its cloudwatch log group's name
END RequestId: cf8065ed-ff19-4e66-ae54-195d9c6b976b
REPORT RequestId: cf8065ed-ff19-4e66-ae54-195d9c6b976b Init Duration: 0.71 ms Duration: 343.71 ms Billed Duration: 344 ms Memory Size: 256 MB Max Memory Used: 256 MB
huh,, i have no idea! # outpustream result
'컴퓨터공학 > 서버리스' 카테고리의 다른 글
[AWS][API Gateway] API Gateway 유형에 따른 ALB Private Integration 차이 /w VPC Link (2) | 2022.09.08 |
---|---|
[AWS][SAM] 오류 핸들링 (0) | 2022.04.04 |
[AWS][SAM][강의노트] 자바 런타임에서 람다 클래스의 수명 (0) | 2022.03.24 |
[AWS][SAM][강의노트] sam init - 프로젝트 시작하기 (0) | 2022.03.11 |