다음과 같은 API 요청과 API 응답을 가지는 REST API를 Lambda 함수와 API Gateway를 이용하여 구축해본다.
API 요청
GET /devices
API 응답
{
"things": [
{
"thingName": "string",
"thingArn": "string"
},
...
]
}
생성된 ListingDeviceLambdaJavaProject의 pom.xml 파일을 열고, <dependencies> 태그 안에 aws-java-sdk-iot에 대한 의존성을 추가한 후에, 파일을 저장합니다.
<dependencies>
...
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-iot</artifactId>
</dependency>
</dependencies>
Eclipse 프로젝트 탐색기를 사용하여 ListingDeviceLambdaJavaProject 프로젝트에서 ListingDeviceHandler.java를 열고, 다음 코드로 바꿉니다.
import java.util.List;
import com.amazonaws.services.iot.AWSIot;
import com.amazonaws.services.iot.AWSIotClientBuilder;
import com.amazonaws.services.iot.model.ListThingsRequest;
import com.amazonaws.services.iot.model.ListThingsResult;
import com.amazonaws.services.iot.model.ThingAttribute;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
public class ListingDeviceHandler implements RequestHandler<Object, String> {
@Override
public String handleRequest(Object input, Context context) {
// AWSIot 객체를 얻는다.
AWSIot iot = AWSIotClientBuilder.standard().build();
// ListThingsRequest 객체 설정.
ListThingsRequest listThingsRequest = new ListThingsRequest();
// listThings 메소드 호출하여 결과 얻음.
ListThingsResult result = iot.listThings(listThingsRequest);
// result 객체로부터 API 응답모델 문자열 생성하여 반
return getResponse(result);
}
/**
* ListThingsResult 객체인 result로 부터 ThingName과 ThingArn을 얻어서 Json문자 형식의
* 응답모델을 만들어 반환한다.
* {
* "things": [
* {
* "thingName": "string",
* "thingArn": "string"
* },
* ...
* ]
* }
*/
private String getResponse(ListThingsResult result) {
List<ThingAttribute> things = result.getThings();
String response = "{ \"things\": [";
for (int i =0; i<things.size(); i++) {
if (i!=0)
response +=",";
response += String.format("{\"thingName\":\"%s\", \"thingArn\":\"%s\"}",
things.get(i).getThingName(),
things.get(i).getThingArn());
}
response += "]}";
return response;
}
}
Lambda에 함수를 업로드하려면, Eclipse 코드 창에서 마우스 오른쪽 버튼을 클릭하고 [AWS Lambda]와 [Upload function to AWS Lambda]를 차례대로 선택합니다.
[Select Target Lambda Function] 페이지에서 사용할 AWS 리전을 선택합니다. 이 리전은 Amazon S3 버킷에 대해 선택한 리전과 동일해야 합니다.
새 Lambda 함수 생성을 선택하고 함수 이름(예: ListThingsFunction)을 입력한 후, [Next]를 선택합니다.
함수 구성(Function Configuration 페이지에서 대상 Lambda 함수에 대한 설명을 입력하고 함수에서 사용할 IAM 역할 선택합니다.
Lambda 함수 코드를 저장할 S3 버킷을 선택합니다. 만약 새로운 Amazon S3 버킷을 생성하고 싶은 경우에는 생성 버튼을 클릭하고 버킷 생성 대화 상자에 버킷 이름을 입력합니다.
Finish를 선택하여 Lambda 함수를 AWS에 업로드합니다.
Lambda 함수를 실행하려면, Eclipse 코드 창에서 마우스 오른쪽 버튼을 클릭하고 AWS Lambda를 선택한 후 Run Function on AWS Lambda(AWS Lambda에서 함수 실행)를 선택합니다.
Invoke 버튼을 클릭한 후, Eclipse Console 창에 다음과 같은 결과가 출력되는 지 확인합니다.
Skip uploading function code since no local change is found...
Invoking function...
==================== FUNCTION OUTPUT ====================
"{ \things\": [{\"thingName\":\"MyMKRWiFi1010\", \"thingArn\":\"arn:aws:iot:ap-northeast-2:171820622505:thing/MyMKRWiFi1010\"},{\"thingName\":\"MyMKRWiFi1010-2\", \"thingArn\":\"arn:aws:iot:ap-northeast-2:171820622505:thing/MyMKRWiFi1010-2\"}]}"
==================== FUNCTION LOG OUTPUT ====================
START RequestId: a0e3a9ed-38fd-499d-af48-a9cbb03fbe2c Version: $LATEST
END RequestId: a0e3a9ed-38fd-499d-af48-a9cbb03fbe2c
REPORT RequestId: a0e3a9ed-38fd-499d-af48-a9cbb03fbe2c Duration: 173.25 ms Billed Duration: 200 ms Memory Size: 512 MB Max Memory Used: 129 MB
Lambda 함수에 대한 권한 추가 팝업이 나타나면(Lambda 함수를 호출하기 위해 API Gateway에 권한을 부여하려고 합니다....”), 확인을 선택하여 API Gateway에 해당 권한을 부여합니다.
클라이언트 부분의 테스트를 클릭합니다.
아무 입력 없이 테스트버튼을 클릭하여 다음과 같은 결과가 나오는 지 확인합니다.
JavaScript는 Cross-Origin Resource Sharing (CORS) 요청을 기본적으로 제한합니다. 즉, JavaScript 코드가 동일 서버 내의 리소스를 접근하는 것은 허용하지만, 다른 서버의 리소스를 사용하고자 하는 경우에는 CORS 헤더 정보가 포함되어 있어야 합니다.
REST API 리소스에 대해 CORS 지원 활성화
2단계를 완료하면 API를 생성했지만 아직 실제로 사용할 수는 없습니다. 배포해야 하기 때문입니다.
웹 브라우저 주소창에 호출 URL/devices
을 입력한 후 엔터를 쳐 봅니다.
2.1절에서 정의한 응답모델과 동일한 형식의 JSon 문자열이 반환된 것을 확인할 수 있습니다.
나의 디바이스 목록 조회
list_devices.html 시작 html 페이지
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>AWS Open API Sample</title>
<!-- JQuery 라이브러리 설정 -->
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<!-- 디바이스 조회 자바스크립트 로딩-->
<script src="list_devices.js"></script>
</head>
<body>
<h3>My AWS API Sample</h3>
<h4> 나의 디바이스 목록 <input type="button" value="조회" onclick="Start();" />
</h4>
<table id="mytable">
<thead style="background-color:lightgrey">
<th>디바이스 명</th>
<th>디바이스 ARN</th>
</thead>
<tbody> </tbody>
</table>
<div id="result">No Data</div>
</body>
</html>
list_devices.js: JQuery 기반 Javascript 코드
// API 시작
function Start() {
invokeAPI();
emptyTable();
}
var invokeAPI = function() {
// 디바이스 조회 URI
// prod 스테이지 편집기의 맨 위에 있는 "호출 URL/devices"로 대체해야 함
var API_URI = 'https://XXXXXXXXXX.execute-api.ap-northeast-2.amazonaws.com/prod/devices';
$.ajax(API_URI, {
method: 'GET',
contentType: "application/json",
success: function (data, status, xhr) {
var result = JSON.parse(data);
setDataList(result.things); // 성공시, 데이터 출력을 위한 함수 호출
console.log(data);
},
error: function(xhr,status,e){
// document.getElementById("result").innerHTML="Error";
alert("error");
}
});
};
// 테이블 데이터 삭제
var emptyTable = function() {
$( '#mytable > tbody').empty();
document.getElementById("result").innerHTML="조회 중입니다.";
}
// 데이터 출력을 위한 함수
var setDataList = function(data){
$( '#mytable > tbody').empty();
data.forEach(function(v){
var tr1 = document.createElement("tr");
var td1 = document.createElement("td");
var td2 = document.createElement("td");
td1.innerText = v.thingName;
td2.innerText = v.thingArn;
tr1.appendChild(td1);
tr1.appendChild(td2);
$("table").append(tr1);
})
if(data.length>0){
// 디바이스 목록 조회결과가 있는 경우 데이터가 없습니다 메시지 삭제
document.getElementById("result").innerHTML="";
} else if (data.length ==0) {
document.getElementById("result").innerHTML="No Data";
}
}
실행 화면
초기화면
조회 버튼을 클릭한 후