본문 바로가기
AWS

AWS Lambda 사용법 (SDK 또는 Gateway)

by Jason95 2020. 12. 19.

라우팅은 node.js express의 router 모듈로 하였다.

 

1. AWS SDK 모듈을 통한 통신

var AWS = require('aws-sdk');

AWS SDK 객체 생성

 

AWS.config.region = 'us-east-1';

지역 설정

 

var lambda = new AWS.Lambda({
    "accessKeyId": "AAAAAAAAAAAAAAAAAAAA",
    "secretAccessKey": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
});

람다 객체 생성

 

router.post("/sdk_lambda", function(req, res, next) {
    const param = { "number": req.query.param };
    // const param = { "p1": "/", "p2": "123", "p3": "456" }; // parameter 여러 개
    var params = {
        FunctionName: "function_by_sdk", // or Function ARN
        InvocationType: "RequestResponse",
        Payload: JSON.stringify(param)
    };
    lambda.invoke(params, function(error, data) {
        console.log("error value: " + error);
        //data.Payload is returned as a string, to check it, turn into JSON object
        let payload = JSON.parse(data.Payload);
        if (error) {
            console.log("Error invoking AWS " + error);
        } else {
            if (!payload.errorMessage) {
                console.log("no error");
                res.json({ new_data: payload.body });
                console.log(payload.body);
            } else {
                //Lambda error
                console.log("Lambda error");
                console.log(payload.errorMessage);
            }
        }
    });
});

POST 방식의 라우터 API 선언

 

$.ajax({
    url: '/sdk_lambda?param=' + $('#input_sdk_lambda').val(),
    type: 'POST',
    success: function(data) {
    	$("#show_sdk_lambda").html(JSON.parse(data.new_data).result);
    },
    error: function(e) {
    	console.log(e);
    }	
});

API를 호출하는 Client 코드

 

exports.handler = (event, context, callback) => {
    var num = event.number;
    
    var responseBody = {
        "result": num
    };

    var response = {
        "statusCode": 200,
        "headers": {
            "my_header": "my_value"
        },
        "body": JSON.stringify(responseBody),
        "isBase64Encoded": false
    };
    
    callback(null, response);
};

AWS Lambda Console에 생성한 람다 함수의 내용

 

Deploy 버튼을 눌러 배포가 완료되면

 1) SDK 환경에서 사용 가능

 2) Test 버튼을 눌러서 테스트 가능

 

 

2. AWS Gateway를 통한 통신

router.get("/bus_gateway", function(req, res, next) {
    var url = 'https://aaaaaaaaaa.execute-api.us-east-1.amazonaws.com/3';
    var resource = '/bus';
    var queryParams = '?number=' + req.query.id;
    request({
        url: url + resource + queryParams,
        method: 'GET'
    }, function(error, response, body) {
        if (error) console.log(error);
        console.log("Body = " + body);
        console.log("JSON.parse(body).result" + JSON.parse(body).result);
        res.json({
            new_data: JSON.parse(body).result
        });
    });
});

GET 방식의 API 선언

 

$('#bus').click(function() {
    var id = '200000078';
    $.ajax({
        url: '/bus_gateway?id=' + id,
        type: 'GET',
        success: function(data) {
            // alert(data.new_data);
            var str = "";
            data.new_data.forEach(function(item, index) {
                str += `[${index}] = ${item}<br>`;
            });
            // alert(str);
            $("#show_bus").html(str);
        },
        error: function(e) {
            console.log(e);
        }
    });
});

API를 호출하는 Client 코드

 

AWS Gateway Console에서 bus라는 리소스의 GET 메서드를

function_by_gateway_node_module이라는 이름의 람다 함수와 연결

 

 * '작업' 버튼을 통해 '리소스'를 생성한 뒤, '메서드'를 그 안에 생성하고, 'API 배포' 버튼을 눌러야 실제 환경에 적용됨

 * 'API 배포'시 설정한 배포 스테이지가 URL에 붙게 됨

  ( ex) aaaaaaaaaa.execute-api.us-east-1.amazonaws.com/3 에서 3이 배포 스테이지)

 

var request = require('request'); // 계층(layer) 필요
var cheerio = require("cheerio"); // 계층(layer) 필요

exports.handler = (event, context, callback) => {
    var id = event.queryStringParameters.number;
    var key = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
    
    var url = 'http://openapi.gbis.go.kr/ws/rest/busarrivalservice/station'; // 공공 데이터 포털
    var queryParams = '?' + encodeURIComponent('ServiceKey') + '=' + key; /* Service Key*/
    queryParams += '&' + encodeURIComponent('serviceKey') + '=' + encodeURIComponent(key); /* */
    queryParams += '&' + encodeURIComponent('stationId') + '=' + encodeURIComponent(id); /* */

    request({
        url: url + queryParams,
        method: 'GET'
    }, function(error, response, body) {
        var $ = cheerio.load(body);
        var list = [];
        $("busArrivalList").each(function(index, item) {
            var bus = $(item).find('plateNo1').text();
            list[index] = bus;
        });
        
        var responseBody = {
            "result": list
        };
        
        // console.log(responseBody);
    
        var response = {
            "statusCode": 200,
            "headers": {
                "my_header": "my_value"
            },
            "body": JSON.stringify(responseBody),
            "isBase64Encoded": false
        };
        
        callback(null, response);
    });
}
        

연결된 람다 함수의 내용

(본 함수는 공공데이터포털 URL를 이용해 서버 호출을 하는 코드이므로

공공데이터포털 홈페이지 계정을 통해 '활용신청'을 하고 Key를 발급받아야만 서버 호출 가능함

서버 호출이 불필요한 경우 해당 코드는 삭제하고 자유롭게 수정하여 진행)

 

 * event 객체 안에 있는 parameter를 오류 없이 접근하는 방법

  1) event.number

    - AWS Lambda Console에서 테스트할 때

    - 외부에서 AWS SDK로 호출할 때

  2) event.queryStringParameters.number

    - AWS Gateway Console에서 테스트할 때

    - 외부에서 Gateway API를 통해 호출할 때

 

 * 람다 함수 내에서 require를 통해 모듈(라이브러리) 사용하는 방법

'계층 생성' 버튼 클릭

 

압축 파일로 모듈 업로드 시, 반드시 다음과 같은 디렉토리 구조로 압축

nodejs라는 빈 폴더 안에, nodejs라는 빈 폴더 안에, node_modules라는 폴더 안에, 실제 모듈들이 있도록 하고

최상위 폴더인 nodejs를 압축

모듈은 cmd 창에서 npm install을 통해 설치 가능

 

계층을 연결하기 위하여 'Add a layer' 클릭

 

연결하고자 하는 계층을 선택하고 '추가' 버튼으로 계층 연결 완료