11.2. Node.js 함수 개발

Node.js 함수 프로젝트를 생성한 후에는 제공된 템플릿 파일을 수정하여 비즈니스 로직을 함수에 추가할 수 있습니다. 여기에는 함수 호출 구성 및 반환된 헤더 및 상태 코드가 포함됩니다.

11.2.1. 사전 요구 사항

11.2.2. Node.js 함수 템플릿 구조

Knative(kn) CLI를 사용하여 Node.js 함수를 생성할 때 프로젝트 디렉터리는 일반적인 Node.js 프로젝트와 유사합니다. 유일한 예외는 함수를 구성하는 데 사용되는 추가 func.yaml 파일입니다.

httpevent 트리거 함수 모두 동일한 템플릿 구조를 갖습니다.

템플릿 구조

.
├── func.yaml 1
├── index.js 2
├── package.json 3
├── README.md
└── test 4
    ├── integration.js
    └── unit.js

1
func.yaml 구성 파일은 이미지 이름과 레지스트리를 결정하는 데 사용됩니다.
2
프로젝트에는 단일 함수를 내보내는 index.js 파일이 포함되어야 합니다.
3
템플릿 package.json 파일에 제공된 종속성으로 제한되지 않습니다. 다른 Node.js 프로젝트에서와 마찬가지로 추가 종속 항목을 추가할 수 있습니다.

npm 종속성 추가 예

npm install --save opossum

프로젝트가 배포용으로 빌드되면 이러한 종속 항목은 생성된 런타임 컨테이너 이미지에 포함됩니다.

4
통합 및 테스트 스크립트는 함수 템플릿의 일부로 제공됩니다.

11.2.3. Node.js 함수 호출 정보

Knative(kn) CLI를 사용하여 함수 프로젝트를 생성할 때 CloudEvents에 응답하는 프로젝트 또는 간단한 HTTP 요청에 응답하는 프로젝트를 생성할 수 있습니다. Knative의 CloudEvents는 HTTP를 통해 POST 요청으로 전송되므로 함수 유형 모두 수신되는 HTTP 이벤트를 수신하고 응답합니다.

Node.js 함수는 간단한 HTTP 요청을 사용하여 호출할 수 있습니다. 들어오는 요청이 수신되면 context 오브젝트를 첫 번째 매개 변수로 사용하여 함수가 호출됩니다.

11.2.3.1. Node.js 컨텍스트 오브젝트

함수는 context 오브젝트를 첫 번째 매개 변수로 제공하여 호출됩니다. 이 오브젝트는 들어오는 HTTP 요청 정보에 대한 액세스를 제공합니다.

컨텍스트 오브젝트의 예

function handle(context, data)

이 정보에는 HTTP 요청 메서드, 요청과 함께 전송된 쿼리 문자열 또는 헤더, HTTP 버전 및 요청 본문이 포함됩니다. CloudEvent 가 포함된 들어오는 요청은 context.cloudevent 를 사용하여 액세스할 수 있도록 CloudEvent의 들어오는 인스턴스를 컨텍스트 오브젝트에 연결합니다.

11.2.3.1.1. 컨텍스트 오브젝트 메서드

context 오브젝트에는 데이터 값을 수락하고 CloudEvent를 반환하는 단일 메서드 cloudEventResponse()가 있습니다.

Knative 시스템에서 서비스로 배포된 함수가 CloudEvent를 보내는 이벤트 브로커에 의해 호출되는 경우 브로커는 응답을 확인합니다. 응답이 CloudEvent인 경우 브로커가 이 이벤트를 처리합니다.

컨텍스트 오브젝트 메서드 예

// Expects to receive a CloudEvent with customer data
function handle(context, customer) {
  // process the customer
  const processed = handle(customer);
  return context.cloudEventResponse(customer)
    .source('/handle')
    .type('fn.process.customer')
    .response();
}

11.2.3.1.2. CloudEvent 데이터

들어오는 요청이 CloudEvent인 경우 CloudEvent와 관련된 모든 데이터가 이벤트에서 추출되며 두 번째 매개변수로 제공됩니다. 예를 들어 데이터 속성에 다음과 유사한 JSON 문자열이 포함된 CloudEvent가 수신되는 경우 다음과 같이 됩니다.

{
  "customerId": "0123456",
  "productId": "6543210"
}

호출될 때 context 오브젝트 다음에 함수에 대한 두 번째 매개 변수는 customerIdproductId 속성이 있는 JavaScript 오브젝트가 됩니다.

서명 예

function handle(context, data)

이 예제의 data 매개변수는 customerIdproductId 속성을 포함하는 JavaScript 오브젝트입니다.

11.2.4. Node.js 함수 반환 값

함수는 유효한 JavaScript 유형을 반환하거나 반환 값이 없을 수 있습니다. 함수에 반환 값이 지정되지 않고 실패가 표시되지 않으면 호출자는 204 No Content 응답을 받습니다.

또한 함수는 이벤트를 Knative Eventing 시스템으로 푸시하기 위해 CloudEvent 또는 Message 오브젝트를 반환할 수 있습니다. 이 경우 개발자는 CloudEvent 메시징 사양을 이해하고 구현할 필요가 없습니다. 반환된 값의 헤더 및 기타 관련 정보는 추출된 응답으로 전송됩니다.

function handle(context, customer) {
  // process customer and return a new CloudEvent
  return new CloudEvent({
    source: 'customer.processor',
    type: 'customer.processed'
  })
}

11.2.4.1. 헤더 반환

return 오브젝트에 headers 속성을 추가하여 응답 헤더를 설정할 수 있습니다. 이러한 헤더는 추출된 호출에 대한 응답으로 전송됩니다.

응답 헤더의 예

function handle(context, customer) {
  // process customer and return custom headers
  // the response will be '204 No content'
  return { headers: { customerid: customer.id } };
}

11.2.4.2. 상태 코드 반환

statusCode 속성을 return 오브젝트에 추가하여 호출자에게 반환된 상태 코드를 설정할 수 있습니다.

상태 코드 예

function handle(context, customer) {
  // process customer
  if (customer.restricted) {
    return { statusCode: 451 }
  }
}

상태 코드는 함수에서 생성되어 발생하는 오류에 대해 설정할 수 있습니다.

오류 상태 코드의 예

function handle(context, customer) {
  // process customer
  if (customer.restricted) {
    const err = new Error(‘Unavailable for legal reasons’);
    err.statusCode = 451;
    throw err;
  }
}

11.2.5. Node.js 함수 테스트

Node.js 함수는 컴퓨터에서 로컬로 테스트할 수 있습니다. kn func create 를 사용하여 함수를 생성할 때 생성되는 기본 프로젝트에는 몇 가지 간단한 단위 및 통합 테스트가 포함된 테스트 폴더가 있습니다.

사전 요구 사항

  • OpenShift Serverless Operator 및 Knative Serving이 클러스터에 설치되어 있습니다.
  • Knative(kn) CLI가 설치되어 있습니다.
  • kn func create 를 사용하여 함수를 생성했습니다.

프로세스

  1. 함수의 테스트 폴더로 이동합니다.
  2. 테스트를 실행합니다.

    $ npm test

11.2.6. liveness 및 readiness 프로브 값 덮어쓰기

Node.js 함수 활성 상태 및 준비 상태 프로브 값을 덮어쓸 수 있습니다. 이를 통해 함수에서 수행된 상태 점검을 구성할 수 있습니다.

사전 요구 사항

  • OpenShift Serverless Operator 및 Knative Serving이 클러스터에 설치되어 있습니다.
  • Knative(kn) CLI가 설치되어 있습니다.
  • kn func create 를 사용하여 함수를 생성했습니다.

프로세스

  1. 함수 코드에서 다음 인터페이스를 구현하는 Function 개체를 만듭니다.In your function code, create the Function object, which implements the following interface:

    export interface Function {
      init?: () => any; 1
    
      shutdown?: () => any; 2
    
      liveness?: HealthCheck; 3
    
      readiness?: HealthCheck; 4
    
      logLevel?: LogLevel;
    
      handle: CloudEventFunction | HTTPFunction; 5
    }
    1
    서버가 시작되기 전에 호출되는 초기화 함수입니다. 이 함수는 선택 사항이며 동기여야 합니다.
    2
    서버가 중지되면 호출되는 shutdown 함수입니다. 이 함수는 선택 사항이며 동기여야 합니다.
    3
    서버가 활성 상태인지 확인하기 위해 호출되는 활성 함수입니다. 이 기능은 선택 사항이며 서버가 활성 상태인 경우 200/OK를 반환해야 합니다.
    4
    서버가 요청을 수락할 준비가 되었는지 확인하기 위해 라는 준비 함수입니다. 이 기능은 선택 사항이며 서버가 준비되면 200/OK를 반환해야 합니다.
    5
    HTTP 요청을 처리하는 함수입니다.

    예를 들어 index.js 파일에 다음 코드를 추가합니다.

    const Function = {
    
      handle: (context, body) => {
        // The function logic goes here
        return 'function called'
      },
    
      liveness: () => {
        process.stdout.write('In liveness\n');
        return 'ok, alive';
      }, 1
    
      readiness: () => {
        process.stdout.write('In readiness\n');
        return 'ok, ready';
      } 2
    };
    
    Function.liveness.path = '/alive'; 3
    Function.readiness.path = '/ready'; 4
    
    module.exports = Function;
    1
    사용자 정의 활성 기능.
    2
    사용자 정의 준비 기능.
    3
    사용자 정의 활성 엔드 포인트.
    4
    사용자 정의 준비 엔드 포인트.

    Function.liveness.pathFunction.readiness.path 의 대안으로 LIVENESS_URLREADINESS_URL 환경 변수를 사용하여 사용자 정의 끝점을 지정할 수 있습니다.

    run:
      envs:
      - name: LIVENESS_URL
        value: /alive 1
      - name: READINESS_URL
        value: /ready 2
    1
    활성 경로, 여기서 /alive 로 설정합니다.
    2
    준비 상태 경로입니다. /ready 로 설정합니다.
  2. 새 끝점을 func.yaml 파일에 추가하여 Knative 서비스의 컨테이너에 올바르게 바인딩됩니다.

    deploy:
      healthEndpoints:
        liveness: /alive
        readiness: /ready

11.2.7. Node.js 컨텍스트 오브젝트 참조

context 오브젝트에는 함수 개발자가 액세스할 수 있는 여러 속성이 있습니다. 이러한 속성에 액세스하면 HTTP 요청에 대한 정보를 제공하고 클러스터 로그에 출력을 작성할 수 있습니다.

11.2.7.1. log

클러스터 로그에 출력을 작성하는 데 사용할 수 있는 로깅 오브젝트를 제공합니다. 로그는 Pino 로깅 API를 따릅니다.

로그 예

function handle(context) {
  context.log.info(“Processing customer”);
}

kn func invoke 명령을 사용하여 함수에 액세스할 수 있습니다.

명령 예

$ kn func invoke --target 'http://example.function.com'

출력 예

{"level":30,"time":1604511655265,"pid":3430203,"hostname":"localhost.localdomain","reqId":1,"msg":"Processing customer"}

로그 수준을 fatal,error,warn,info,debug,trace 또는 silent 중 하나로 변경할 수 있습니다. 이렇게 하려면 config 명령을 사용하여 해당 값 중 하나를 환경 변수 FujiNC _LOG_LEVEL에 할당하여 logLevel 값을 변경합니다.

11.2.7.2. query

요청에 대한 쿼리 문자열을 키-값 쌍으로 반환합니다. 이러한 속성은 컨텍스트 오브젝트 자체에서도 확인할 수 있습니다.

예제 쿼리

function handle(context) {
  // Log the 'name' query parameter
  context.log.info(context.query.name);
  // Query parameters are also attached to the context
  context.log.info(context.name);
}

kn func invoke 명령을 사용하여 함수에 액세스할 수 있습니다.

명령 예

$ kn func invoke --target 'http://example.com?name=tiger'

출력 예

{"level":30,"time":1604511655265,"pid":3430203,"hostname":"localhost.localdomain","reqId":1,"msg":"tiger"}

11.2.7.3. body

필요한 경우 요청 본문을 반환합니다. 요청 본문에 JSON 코드가 포함된 경우 속성을 직접 사용할 수 있도록 구문 분석됩니다.

본문의 예

function handle(context) {
  // log the incoming request body's 'hello' parameter
  context.log.info(context.body.hello);
}

curl 명령을 사용하여 이를 호출하여 함수에 액세스할 수 있습니다.

명령 예

$ kn func invoke -d '{"Hello": "world"}'

출력 예

{"level":30,"time":1604511655265,"pid":3430203,"hostname":"localhost.localdomain","reqId":1,"msg":"world"}

11.2.7.4. headers

HTTP 요청 헤더를 오브젝트로 반환합니다.

헤더 예

function handle(context) {
  context.log.info(context.headers["custom-header"]);
}

kn func invoke 명령을 사용하여 함수에 액세스할 수 있습니다.

명령 예

$ kn func invoke --target 'http://example.function.com'

출력 예

{"level":30,"time":1604511655265,"pid":3430203,"hostname":"localhost.localdomain","reqId":1,"msg":"some-value"}

11.2.7.5. HTTP 요청

method
HTTP 요청 메서드를 문자열로 반환합니다.
httpVersion
HTTP 버전을 문자열로 반환합니다.
httpVersionMajor
HTTP 주요 버전 번호를 문자열로 반환합니다.
httpVersionMinor
HTTP 마이너 버전 번호를 문자열로 반환합니다.

11.2.8. 다음 단계