- 인쇄
- PDF
웹 액션
- 인쇄
- PDF
네이버 클라우드 플랫폼 콘솔의 Cloud Functions > Action에서 웹 속성의 액션을 설정할 수 있습니다. 웹 액션은 웹 서비스를 제공할 수 있는 Cloud Functions의 액션입니다. 간단한 코드 작성만으로도 http, html, svg, json, text 등 형식의 웹 페이지나 데이터 등을 인터넷에 공개할 수 있습니다.
만약 별도의 인증 로직이 필요하다면 원하는 인증 로직을 액션 코드에 직접 구현하여 이용하거나, 네이버 클라우드 플랫폼의 API Gateway를 이용하여 웹 액션에 연결한 외부 연결 주소에 API Key나 IAM 인증 설정을 추가하여 사용할 수 있습니다.
생성한 액션을 실행하고 모니터링하는 방법은 Action/Trigger 실행과 Action을 참고해 주십시오.
웹 액션 설정
모든 타입(기본, 시퀀스)의 액션에 대해 웹 속성을 True로 설정할 수 있습니다. 액션 생성 시 웹 액션을 설정하는 방법은 다음과 같습니다.
- 웹 속성의 액션을 생성해 주십시오.
function main({name}) { var msg = 'you did not tell me who you are.'; if (name) { msg = `hello ${name}!` } return {body: `<html><body><h3>${msg}</h3></body></html>`} }
- 외부 연결 주소를 설정해 주십시오.
- 외부 연결 주소 설정 방법: Action/Trigger 실행 참고
- 호출하여 결과값을 확인해 주십시오.
- 요청 형식
$ curl --header "Content-Type: application/json" \ --data '{"name":"cloud functions"}' \ --request POST https://{product_id}.apigw.ntruss.com/{api_name}/{stage_name}/{resource_name}/http
- 응답 형식
<html><body><h3>hello cloud functions!</h3></body></html>
HTTP 요청 처리
웹 액션이 아닌 일반적인 액션의 경우 인증이 있어야 실행될 수 있으며, 반드시 json 형식의 객체를 반환해야 합니다. 반면 웹 액션은 인증 없이 실행될 수 있으며 headers, statusCode, body 등 다양한 콘텐츠로 응답하는 HTTP 핸들러 구현에 사용할 수 있습니다.
웹 액션도 일반 액션과 동일하게 json 형식의 객체를 반환해야 하지만 json 객체의 최상위 속성으로 다음 중 하나 이상을 포함하는 경우 Cloud Functions 시스템 컨트롤러에서 웹 액션을 다르게 처리합니다.
headers
: 키가 헤더 이름이고 문자열, 숫자 또는 boolean 값으로 이루어져 있는 json 객체. 하나의 헤더로 여러 값들을 보내려면 헤더의 값이 json 배열로 이루어져 있어야 함statusCode
: 유효한 HTTP 상태 코드. body가 비어 있는 경우 204 No Content 리턴(기본값: 200 OK)body
: 일반 텍스트, json 객체, 배열 문자열, base64로 인코딩된 바이너리 데이터(기본값: 빈 응답).
body
가 null
인 경우, 빈 문자열(""
)인 경우, undefined인 경우 콘텐츠가 없는 것으로 판단합니다.
Cloud Functions 시스템 컨트롤러는 요청이나 응답 종료 시 액션에서 지정한 헤더를 HTTP 클라이언트에게 전달하며, HTTP 클라이언트는 상태 코드로 응답합니다. body는 응답의 body로 전달됩니다. content-type header
가 결과의 headers
에 정의되어 있지 않다면 body는 본문이 문자열이 아닌 경우에 대해 application/json
으로 해석되며 이외에는 text/html
로 해석됩니다.
만약 content-type
이 정의되어 있고 응답이 바이너리 데이터이거나 일반 텍스트인 경우 Cloud Functions 시스템 컨트롤러는 필요에 따라 base64 디코더로 문자열을 디코딩합니다. 이 때 본문이 올바르게 디코딩되지 않았다면 오류로 판단하게 됩니다.
Raw HTTP 처리
Cloud Functions는 Akka Http 프레임 워크를 사용하여 바이너리와 일반 텍스트 콘텐츠 타입을 판단하기 때문에 Cloud Functions의 웹 액션은 HTTP 본문을 효과적으로 해석하고 처리할 수 있습니다. 예컨대 요청 시 사용한 HTTP 메서드를 확인하기 위해 params.__ow_method
값을 코드에서 사용할 수 있습니다. 참고할 수 있는 예제 코드와 실행 결과는 다음과 같습니다.
- 예제 코드
function main(params) { return params }
- 실행 결과
$ curl https://{Action_URL}/json?key=value -X POST -H "Content-Type: application/json" -d '{"key":"value"}' { "response": { "__ow_method": "post", "__ow_body": "", "__ow_headers": { "accept": "*/*", "connection": "close", "content-length": "15", "content-type": "application/json", "host": "172.17.0.1", "user-agent": "curl/7.43.0" }, "__ow_path": "", "key": "value" } }
Base64 타입의 바이너리 디코딩
Raw HTTP로 처리 시 content-type이 바이너리인 경우 __ow_body
콘텐츠는 Base64로 인코딩되어 있음을 예상할 수 있습니다. 다음의 예제 코드를 통해 다양한 런타임 환경에서 인코딩된 본문을 어떻게 다루는지 확인할 수 있습니다.
- Node.js
function main(args) { decoded = new Buffer(args.__ow_body, 'base64').toString('utf-8') return {body: decoded} }
- Python
def main(args): try: decoded = args['__ow_body'].decode('base64').strip() return {"body": decoded} except: return {"body": "Could not decode body from Base64."}
- Swift
extension String { func base64Decode() -> String? { guard let data = Data(base64Encoded: self) else { return nil } return String(data: data, encoding: .utf8) } } func main(args: [String:Any]) -> [String:Any] { if let body = args["__ow_body"] as? String { if let decoded = body.base64Decode() { return [ "body" : decoded ] } } return ["body": "Could not decode body from Base64."] }
위 예제 코드의 함수를 저장하고 Raw HTTP 웹 액션을 생성하여 실제 웹 작업을 테스트할 수 있습니다. NodeJS 함수를 decode
액션으로 저장한 다음 명령어를 실행한 결과 예제는 다음과 같습니다.
$ curl -k -H "Content-Type: text/plain" -X POST -d "RGVjb2RlZCBib2R5" https://{Action_URL}/json
{
"body": "Decoded body"
}
OPTIONS 요청
OPTIONS 요청은 기본적으로 Cors 헤더가 응답 헤더에 자동 추가됩니다. 이러한 헤더들은 모든 Origin을 허용하며, OPTIONS, GET, DELETE, POST, PUT, HEAD, PATCH 메서드를 허용합니다. 추가적으로 HTTP 요청이 존재하는 경우 Access-Control-Request-Headers
헤더는 Access-Control-Allow-Headers
헤더로 에코백됩니다. 생성되는 기본값은 다음과 같습니다.
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: OPTIONS, GET, DELETE, POST, PUT, HEAD, PATCH
Access-Control-Allow-Headers: Authorization, Content-Type
OPTIONS 요청은 웹 액션에 의해 수동으로 처리될 수도 있습니다. 이를 위해 web-custom-options
옵션을 true
값으로 활성화시켜야 합니다. 이 기능이 활성화되면 Cors 헤더는 더 이상 자동으로 추가되지 않기 때문에 사용자가 직접 프로그래밍하여 헤더를 결정한 다음 추가해야 합니다. OPTIONS 요청에 대해 사용자가 수동으로 응답하는 예제 코드는 다음과 같습니다.
function main(params) {
if (params.__ow_method == "options") {
return {
headers: {
'Access-Control-Allow-Methods': 'OPTIONS, GET',
'Access-Control-Allow-Origin': 'example.com'
},
statusCode: 200
}
}
}
위 함수를 저장한 다음 명령어를 실행한 결과 예제는 다음과 같습니다.
$ curl https://{Action_URL}/http -kvX OPTIONS
< HTTP/1.1 200 OK
< Server: nginx/1.11.13
< Content-Length: 0
< Connection: keep-alive
< Access-Control-Allow-Methods: OPTIONS, GET
< Access-Control-Allow-Origin: example.com
추가 기능
웹 액션에서 제공하는 추가 기능은 다음과 같습니다.
Content extensions
원하는 콘텐츠 유형을 /json
, /html
, /http
, /svg
, /text
중 하나로 지정합니다. URI의 액션 이름에 확장자를 추가함으로써 수행되며 /{web_action_url}
액션은 HTTP 응답을 받기 위해 /{web_action_url}/http
처럼 사용됩니다.
콘텐츠 유형이 지정되지 않으면 액션이 실행되지 않습니다.
Query and body parameters as input
액션은 요청 본문의 파라미터뿐만 아니라 쿼리 파라미터를 받습니다. 이러한 파라미터 병합 시 우선 순위는 패키지 파라미터, 액션 파라미터, 쿼리 파라미터 순이며 겹치는 경우 각각 이전 값들을 순서대로 재정의합니다. 예를 들어 /{Web_Action_URL}/http/?name=Jane
와 같은 요청은 입력 파라미터로 {name: "Jane"}
를 액션에 전달합니다.
Form data
표준 application/json
외에도 웹 액션은 URL 인코딩된 form data application/x-www-form-urlencoded data
도 입력으로 받을 수 있습니다.
Activation via multiple HTTP verbs
웹 액션은 HTTP 메서드(GET
, POST
, PUT
, PATCH
, DELETE
, HEAD
, OPTIONS
)를 통해 실행될 수 있습니다.
Non JSON body and raw HTTP entity handling
웹 액션은 json 객체 외 HTTP 요청 body를 처리할 수 있으며 이해하기 힘든 값(바이너리가 아닌 경우 일반 문자열이나 base64로 인코딩된 문자열)도 항상 전달받도록 선택할 수 있습니다.
오류 처리
웹 액션이 실패한 경우 다음과 같은 두 가지 실패 모드로 처리됩니다.
- application error: 액션이 에러 속성을 가지는 최상위 json 객체를 리턴. catch 예외와 유사
- developer error: 액션이 실패하고 응답을 만들지 않을 때 발생. uncaught 예외와 유사
application error는 사용자가 지정하여 처리해야 하며, 웹 액션의 콘텐츠 유형에 따라 오류 메시지를 생성하는 것을 권장합니다. 예를 들어 .http
확장자와 함께 사용되는 웹 액션은 확장자의 content-type과 오류 응답 액션의 content-type이 일치하도록 {error: { statusCode: 400 }
와 같은 HTTP 응답을 반환하도록 오류 메시지를 생성할 수 있습니다.