Azure Functions용 Node.js 프로그래밍 모델 버전 4로 마이그레이션

이 문서에서는 Node.js 프로그래밍 모델 버전 3과 버전 4의 차이점과 기존 v3 앱을 업그레이드하는 방법을 설명합니다. 기존 v3 앱을 업그레이드하는 대신 새 v4 앱을 만들려면 VS Code(Visual Studio Code) 또는 Azure Functions Core Tools 자습서를 참조하세요. 이 문서에서는 "팁" 경고를 사용하여 앱을 업그레이드하기 위해 취해야 할 가장 중요하고 구체적인 작업을 강조 표시합니다.

버전 4는 Node.js 개발자에게 다음과 같은 이점을 제공하도록 설계되었습니다.

  • Node.js 개발자에게 친숙하고 직관적인 환경을 제공합니다.
  • 전체 사용자 지정을 지원하여 파일 구조를 유연하게 만듭니다.
  • 함수 구성을 정의하기 위해 코드 중심 방식으로 전환합니다.

고려 사항

  • Node.js 프로그래밍 모델을 Azure Functions 런타임과 혼동하면 안 됩니다.
    • 프로그래밍 모델: 코드를 작성하는 방법을 정의하고 JavaScript 및 TypeScript에만 적용됩니다.
    • 런타임: Azure Functions의 기본 동작을 정의하고 모든 언어에서 공유됩니다.
  • 프로그래밍 모델 버전은 @azure/functions npm 패키지 버전과 엄격하게 연결되어 있습니다. 런타임과 독립적으로 버전이 지정됩니다. 런타임과 프로그래밍 모델 모두 최신 주 버전으로 숫자 4를 사용하지만 이는 우연의 일치입니다.
  • 동일한 함수 앱에서 v3 및 v4 프로그래밍 모델을 혼합할 수 없습니다. 앱에 하나의 v4 함수를 등록하는 즉시 function.json 파일에 등록된 모든 v3 함수는 무시됩니다.

요구 사항

Node.js 프로그래밍 모델 버전 4에는 다음과 같은 최소 버전이 필요합니다.

npm 패키지 포함

v4에서 @azure/functions npm 패키지에는 Node.js 프로그래밍 모델을 지원하는 기본 소스 코드가 포함되어 있습니다. 이전 버전에서는 해당 코드가 Azure에서 직접 제공되었으며 npm 패키지에는 TypeScript 형식만 있었습니다. 이제 TypeScript 및 JavaScript 앱 모두에 이 패키지를 포함해야 합니다. 기존 v3 앱용 패키지를 포함할 수 있으나 필수는 아닙니다.

@azure/functions 패키지가 package.json 파일의 dependencies 섹션(devDependencies 아님)에 나열되어 있는지 확인합니다. 다음 명령을 사용하여 v4를 설치할 수 있습니다.

npm install @azure/functions

앱 진입점 설정

프로그래밍 모델 v4에서는 원하는 대로 코드를 구성할 수 있습니다. 앱 루트에 필요한 유일한 파일은 host.jsonpackage.json입니다.

그렇지 않으면 package.json 파일에서 main 필드를 설정하여 파일 구조를 정의합니다. GLOB 패턴을 사용하여 main 필드를 단일 파일 또는 여러 파일로 설정할 수 있습니다. 다음 표에서는 main 필드의 예제 값을 보여 줍니다.

예제 설명
src/index.js 단일 루트 파일에서 함수를 등록합니다.
src/functions/*.js 자체 파일에서 각 함수를 등록합니다.
src/{index.js,functions/*.js} 자체 파일에서 각 함수를 등록하지만 일반 앱 수준 코드에 대한 루트 파일이 있는 조합입니다.
예제 설명
dist/src/index.js 단일 루트 파일에서 함수를 등록합니다.
dist/src/functions/*.js 자체 파일에서 각 함수를 등록합니다.
dist/src/{index.js,functions/*.js} 자체 파일에서 각 함수를 등록하지만 일반 앱 수준 코드에 대한 루트 파일이 있는 조합입니다.

package.json 파일에 main 필드를 정의했는지 확인합니다.

인수 순서 전환

호출 컨텍스트 대신 트리거 입력이 이제 함수 처리기에 대한 첫 번째 인수입니다. 이제 두 번째 인수인 호출 컨텍스트는 v4에서 간소화되었으며 트리거 입력만큼 필요하지 않습니다. 사용하지 않을 경우에는 꺼두면 됩니다.

인수의 순서를 바꿉니다. 예를 들어, HTTP 트리거를 사용하는 경우 (context, request)(request, context)로 전환하거나 컨텍스트를 사용하지 않는 경우 (request)로 전환합니다.

코드에서 함수 정의

더 이상 별도의 function.json 구성 파일을 만들고 유지 관리할 필요가 없습니다. 이제 TypeScript 또는 JavaScript 파일에서 직접 함수를 완전히 정의할 수 있습니다. 또한 이제 많은 속성에 기본값이 있으므로 매번 지정할 필요가 없습니다.

const { app } = require('@azure/functions');

app.http('httpTrigger1', {
    methods: ['GET', 'POST'],
    authLevel: 'anonymous',
    handler: async (request, context) => {
        context.log(`Http function processed request for url "${request.url}"`);

        const name = request.query.get('name') || (await request.text()) || 'world';

        return { body: `Hello, ${name}!` };
    },
});
import { app, HttpRequest, HttpResponseInit, InvocationContext } from '@azure/functions';

export async function httpTrigger1(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
    context.log(`Http function processed request for url "${request.url}"`);

    const name = request.query.get('name') || (await request.text()) || 'world';

    return { body: `Hello, ${name}!` };
}

app.http('httpTrigger1', {
    methods: ['GET', 'POST'],
    authLevel: 'anonymous',
    handler: httpTrigger1,
});

구성을 function.json 파일에서 코드로 이동합니다. 트리거 형식은 새 모델의 app 개체에 대한 메서드에 해당합니다. 예를 들어, function.json에서 httpTrigger 형식을 사용하는 경우 코드에서 app.http()를 호출하여 함수를 등록합니다. timerTrigger를 사용하는 경우 app.timer()를 호출합니다.

컨텍스트 사용을 검토합니다.

v4에서는 중복을 줄이고 단위 테스트 작성을 더 쉽게 만들기 위해 context 개체가 간소화되었습니다. 예를 들어, 기본 입력 및 출력을 간소화하여 함수 처리기의 인수 및 반환 값으로만 액세스할 수 있도록 했습니다.

더 이상 context 개체의 기본 입력 및 출력에 액세스할 수 없지만 context 개체의 보조 입력 및 출력에는 계속 액세스해야 합니다. 보조 입출력에 대한 자세한 내용은 Node.js 개발자 가이드를 참조하세요.

기본 입력을 인수로 가져오기

기본 입력은 트리거라고도 하며 유일하게 필요한 입력 또는 출력입니다. 트리거는 하나만 있어야 합니다.

버전 4는 첫 번째 인수로 트리거 입력을 가져오는 한 가지 방법만 지원합니다.

async function httpTrigger1(request, context) {
  const onlyOption = request;
async function httpTrigger1(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
  const onlyOption = request;

입력을 가져오기 위해 context.req 또는 context.bindings를 사용하고 있지 않은지 확인합니다.

기본 출력을 반환 값으로 설정

버전 4는 반환 값을 통해 기본 출력을 설정하는 한 가지 방법만 지원합니다.

return { 
  body: `Hello, ${name}!` 
};
async function httpTrigger1(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> {
    // ...
    return { 
      body: `Hello, ${name}!` 
    };
}

출력을 context 개체로 설정하는 대신 항상 함수 처리기에서 반환하는지 확인합니다.

컨텍스트 로깅

v4에서 로깅 메서드는 다음 예제와 같이 루트 context 개체로 이동되었습니다. 로깅에 대한 자세한 내용은 Node.js 개발자 가이드를 참조하세요.

context.log('This is an info log');
context.error('This is an error');
context.warn('This is an error');

테스트 컨텍스트 만들기

버전 3은 Azure Functions 런타임 외부에서 호출 컨텍스트 만들기를 지원하지 않으므로 단위 테스트 작성이 어려울 수 있습니다. 버전 4에서는 호출 컨텍스트의 인스턴스를 만들 수 있지만, 테스트 중 정보는 직접 추가하지 않는 한 자세히 표시되지 않습니다.

const testInvocationContext = new InvocationContext({
  functionName: 'testFunctionName',
  invocationId: 'testInvocationId'
});

HTTP 형식 사용을 검토합니다.

HTTP 요청 및 응답 형식은 이제 페치 표준의 하위 집합입니다. 더 이상 Azure Functions에 고유하지 않습니다.

형식은 Node.js의 undici 패키지를 사용합니다. 이 패키지는 페치 표준을 따르며 Node.js 코어에 현재 통합 중입니다.

HttpRequest

  • 본문 수신하려는 형식과 관련된 메서드를 사용하여 본문에 액세스할 수 있습니다.

    const body = await request.text();
    const body = await request.json();
    const body = await request.formData();
    const body = await request.arrayBuffer();
    const body = await request.blob();
    
  • 헤더:

    const header = request.headers.get('content-type');
    
  • 쿼리 매개 변수;

    const name = request.query.get('name');
    

HttpResponse

  • 상태:

    return { status: 200 };
    
  • 본문:

    body 속성을 사용하여 string 또는 Buffer와 같은 대부분의 형식을 반환합니다.

    return { body: "Hello, world!" };
    

    JSON 응답을 반환하는 가장 쉬운 방법은 jsonBody 속성을 사용합니다.

    return { jsonBody: { hello: "world" } };
    
  • 헤더. HttpResponse 클래스를 사용하는지 아니면 HttpResponseInit 인터페이스를 사용하는지에 따라 두 가지 방법으로 헤더를 설정할 수 있습니다.

    const response = new HttpResponse();
    response.headers.set('content-type', 'application/json');
    return response;
    
    return {
      headers: { 'content-type': 'application/json' }
    };
    

새 메서드와 일치하도록 HTTP 요청 또는 응답 형식을 사용하여 논리를 업데이트합니다.

새 메서드와 일치하도록 HTTP 요청 또는 응답 형식을 사용하여 논리를 업데이트합니다. 이전 메서드를 사용하는지 식별할 수 있도록 TypeScript 빌드 오류가 발생합니다.

문제 해결

Node.js 문제 해결 가이드를 참조하세요.