자습서: Azure Functions & Mac용 Visual Studio 시작

Important

Mac용 Visual Studio Microsoft 에 따라 2024년 8월 31일에 사용 중지될 예정입니다. 최신 수명 주기 정책입니다. Mac용 Visual Studio 계속 사용할 수 있지만 Mac의 개발자를 위한 몇 가지 다른 옵션(예: VS Code용 새 C# Dev Kit 확장의 미리 보기 버전)이 있습니다.

지원 타임라인 및 대안에 대해 자세히 알아봅니다.

이 연습에서는 Mac용 Visual Studio를 사용하여 Azure Functions 빌드를 시작하는 방법을 알아봅니다. 또한 Azure Functions 개발자가 사용할 수 있는 다양한 종류의 바인딩 및 트리거 중 하나를 나타내는 Azure Storage 테이블과 통합됩니다.

목표

  • 로컬 Azure Functions 만들기 및 디버그
  • 웹 및 Azure Storage 리소스와 통합
  • 여러 Azure Functions가 포함된 워크플로 조정

요구 사항

연습 1: Azure Functions 프로젝트 만들기

  1. Mac용 Visual Studio를 시작합니다.

  2. 파일 > 새 솔루션을 선택합니다.

  3. 클라우드 > 일반 범주에서 Azure Functions 템플릿을 선택합니다. C#을 사용하여 Azure Functions를 호스트하는 .NET 클래스 라이브러리를 만듭니다. 다음을 클릭합니다.

    Azure Functions template selection

  4. 프로젝트 이름"AzureFunctionsLab"을 설정하고 만들기를 클릭합니다.

    naming and creating your Azure function project

  5. 솔루션 창에서 노드를 확장합니다. 기본 프로젝트 템플릿에는 Newtonsoft.Json 패키지뿐 아니라 여러 Azure WebJobs 패키지에 대한 NuGet 참조가 포함됩니다.

    또한 호스트에 대한 전역 구성 옵션을 설명하는 host.json과, 서비스 설정 구성을 위한 local.settings.json 등 3개 파일이 포함됩니다. - 프로젝트 템플릿은 기본 HttpTrigger도 만듭니다. 이 연습을 위해 프로젝트에서 HttpTrigger.cs 파일을 삭제해야 합니다.

    local.settings.json을 엽니다. 기본적으로 두 개의 빈 연결 문자열 설정을 갖습니다.

    solution window displaying local.settings.json file

연습 2: Azure Storage 계정 만들기

  1. https://portal.azure.com에서 Azure 계정에 로그온합니다.

  2. 즐겨찾기 섹션에서 화면 왼쪽에 있는 스토리지 계정을 선택합니다.

    favorites section of Azure portal showing storage accounts item

  3. 추가를 선택하여 새 스토리지 계정을 만듭니다.

    Button to add new storage account

  4. 이름에 전역으로 고유한 이름을 입력하고 리소스 그룹에 다시 사용합니다. 다른 모든 항목은 기본값으로 유지할 수 있습니다.

    new storage account details

  5. 만들기를 클릭합니다. 스토리지 계정을 만드는 데 몇 분 정도 걸릴 수 있습니다. 만들어진 후에는 알림이 표시됩니다.

    deployment successful notification

  6. 알림에서 리소스로 이동 단추를 선택합니다.

  7. 선택키 탭을 선택합니다.

    access key setting

  8. 첫 번째 연결 문자열을 복사합니다. 이 문자열은 나중에 Azure Functions와 Azure Storage를 통합하는 데 사용됩니다.

    information for key 1

  9. Mac용 Visual Studio로 돌아와 local.settings.jsonAzureWebJobsStorage 설정으로 전체 연결 문자열을 붙여 넣습니다. 이제 해당 리소스에 액세스가 필요한 함수에 대한 속성에서 설정 이름을 참조할 수 있습니다.

    local settings file with connection key entered

예제 3: Azure 함수 만들기 및 디버깅

  1. 이제 일부 코드를 추가할 준비가 되었습니다. .NET 클래스 라이브러리를 사용할 때 Azure Functions는 고정 메서드로 추가됩니다. 솔루션 창에서 AzureFunctions 프로젝트 노드를 마우스 오른쪽 단추로 클릭하고 추가 > 함수 추가를 선택합니다.

    Add function option

  2. 새 Azure Functions 대화 상자에서 일반 웹후크 템플릿을 선택합니다. 이름추가로 설정하고 확인을 클릭하여 함수를 만듭니다.

    New Azure Functions dialog

  3. 새 파일의 맨 위에 아래 using 지시문을 추가합니다.

    using Microsoft.Azure.WebJobs.Extensions.Http;
    using System.Web;
    using Microsoft.WindowsAzure.Storage.Table;
    
  4. 기존 메서드를 Run 제거하고 다음 메서드를 Azure 함수로 클래스에 추가합니다.

    [FunctionName("Add")]
    public static int Run(
    [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)]
    HttpRequestMessage req,
    TraceWriter log)
    {
        int x = 1;
        int y = 2;
    
        return x + y;
    }
    
  5. 메서드 정의를 하나씩 살펴보겠습니다.

    가장 먼저 볼 수 있는 것은 이 메서드를 Azure 함수로 표시하는 FunctionName 특성입니다. 이 특성은 함수의 공개 이름을 지정합니다. 특성 이름이 반드시 실제 메서드 이름과 일치할 필요는 없습니다.

    New run method with FunctionName attribute highlighted

  6. 다음으로, 메서드가 필수인 public static 메서드로 표시됩니다. 또한 반환 값이 int임을 알 수 있습니다. 메서드 특성을 사용하여 달리 지정하지 않는 한 Azure 함수의 비어 있지 않은 반환 값은 클라이언트에 텍스트로 반환됩니다. 기본적으로 XML로 반환되나 JSON으로 변경할 수 있으며 나중에 이 연습에서 해 볼 것입니다.

    New run method with method initialization highlighted

  7. 첫 번째 매개 변수는 HttpTrigger 특성으로 표시됩니다. 이 메서드가 HTTP 요청에 의해 호출됨을 나타냅니다. 이 특성은 메서드의 권한 부여 수준과 지원하는 동사도 지정합니다(이 경우 "GET"만). 필요에 따라 메서드의 경로를 재정의하고 경로에서 변수를 자동으로 추출하는 방법을 제공하는 경로를 정의할 수도 있습니다. 여기서는 Route가 null이므로 이 메서드의 경로는 기본적으로 /api/Add입니다.

    New run method with parameter highlighted

  8. 메서드에 대한 마지막 매개 변수는 진단 및 오류의 메시지를 기록하는 데 사용할 수 있는 TraceWriter입니다.

    New run method with TraceWriter highlighted

  9. 줄의 여백을 클릭하여 메서드의 반환 줄에 중단점을 설정합니다.

    Breakpoint set at return line

  10. F5 키를 누르거나 실행 > 디버깅 시작을 선택하여 디버그 세션에서 프로젝트를 빌드하고 실행합니다. 또는 실행 단추를 클릭할 수 있습니다. 이 옵션은 모두 동일한 작업을 수행 합니다. 이 연습의 나머지 부분에서는 F5를 언급하지만 본인에게 가장 편안한 방법을 사용하면 됩니다.

    Build and Run project

  11. 프로젝트를 실행하면 터미널 애플리케이션이 자동으로 열립니다.

  12. 프로젝트는 이 문서의 뒷부분에서 설명하는 메서드 속성과 파일 규칙에 따라 Azure Functions를 검색하는 프로세스를 거칩니다. 이 경우 단일 Azure 함수를 검색하고 1개의 작업 함수를 "생성"합니다.

    Output of Azure function in Terminal

  13. 시작 메시지의 맨 아래에 Azure Functions 호스트가 HTTP 트리거 API의 URL을 출력합니다. 하나만 있어야 합니다. 해당 URL을 복사하고 새 브라우저 탭에 붙여 넣습니다.

    Azure function API URL

  14. 중단점은 즉시 트리거됩니다. 웹 요청은 함수에 전달되었으며 이제 디버그할 수 있습니다. x 변수 위에 마우스를 놓아 값을 확인합니다.

    Breakpoint triggered

  15. 앞에서 추가에 사용한 것과 같은 메서드를 사용하여 중단점을 제거합니다(여백을 클릭하거나 줄을 선택하고 F9 누르기).

  16. F5를 눌러 실행을 계속합니다.

  17. 브라우저에서 메서드의 XML 결과가 렌더링됩니다. 예상대로 하드 코드된 더하기 연산에서 적당한 합계가 생성됩니다. Safari에 "3"만 표시되는 경우 Safari > 기본 설정 > 고급으로 이동하여 "메뉴 모음에 개발 메뉴 표시" 검사 상자를 검사 페이지를 다시 로드합니다.

  18. Mac용 Visual Studio에서 중지 단추를 클릭하여 디버그 세션을 종료합니다. 새 변경 내용이 반드시 적용되도록 디버깅 세션을 다시 시작합니다(중지한 뒤 실행).

    Stop debugging option

  19. Run 메서드에서 xy 정의를 다음 코드로 바꿉니다. 이 코드는 더하기 연산을 제공된 매개 변수에 따라 동적으로 수행할 수 있게 URL의 쿼리 문자열에서 값을 추출합니다.

    var query = HttpUtility.ParseQueryString(req.RequestUri.Query);
    
    int x = int.Parse(query["x"]);
    
    int y = int.Parse(query["y"]);
    
    return x + y;
    
  20. 애플리케이션을 실행합니다.

  21. 브라우저 창으로 돌아가 /?x=2&y=3 문자열을 URL에 추가합니다. 이제 전체 URL은 http://localhost:7071/api/Add?x=2&y=3입니다. 새 URL로 이동합니다.

  22. 이제 결과가 새 매개 변수를 반영할 것입니다. 다른 값으로 프로젝트를 실행해 봅니다. 오류 검사가 없으므로 올바르지 않거나 누락된 매개 변수에서는 오류가 throw됩니다.

  23. 디버깅 세션을 중지합니다.

연습 4: function.json 작업

  1. 이전 연습에서는 라이브러리에 정의된 Azure 함수에 대한 작업 함수를 "생성"Mac용 Visual Studio 멘션. 이것은 사실 Azure Functions가 런타임에서 메서드 특성을 사용하는 것이 아니라 컴파일 시점 파일 시스템 규칙을 사용하여 Azure Functions를 제공할 방법과 위치를 구성하기 때문입니다. 솔루션 창에서 프로젝트 노드를 마우스 오른쪽 단추로 클릭하고 Finder에 표시를 선택합니다.

    Reveal in Finder menu option

  2. bin/Debug/netstandard2.0이 나올 때까지 파일 시스템에서 아래로 이동합니다. 이름이 Add인 폴더가 있어야 합니다. 이 폴더는 C# 코드의 함수 이름 특성과 일치하도록 만들어졌습니다. 단일 function.json 파일을 표시하기 위해 Add 폴더를 확장합니다. 이 파일은 런타임에서 Azure 함수를 호스트하고 관리하는 데 사용됩니다. 컴파일 시점 지원이 없는 다른 언어 모델(예: C# 스크립트 또는 JavaScript)의 경우 이 폴더를 수동으로 만들어 유지 관리해야 합니다. C# 개발자의 경우 빌드 시 특성 메타데이터에서 자동으로 생성됩니다. function.json을 마우스 오른쪽 단추로 클릭하고 선택하여 Visual Studio에서 엽니다.

    function.json in the file directory

  3. 이 자습서의 이전 단계를 살펴보았으므로 C# 특성에 대한 기본적인 이해가 있을 것입니다. 이를 고려하면 이 JSON에 익숙해야 합니다. 그러나 이전 연습에서 다루지 않은 몇 가지 항목이 있습니다. 예를 들어 각 바인딩에는 direction 설정이 있어야 합니다. 유추하듯이 "in"은 매개 변수가 입력임을, "out"은 매개 변수가 메서드에 대한 반환 값($return 사용) 또는 out 매개 변수임을 나타냅니다. 어셈블리 안에서 scriptFile(이 최종 위치에 상대적) 및 entryPoint 메서드(공개 및 고정)를 지정해야 합니다. 다음 몇 단계에서는 이 모델을 사용하여 사용자 지정 함수 경로를 추가하게 되므로 이 파일의 콘텐츠를 클립보드에 복사합니다.

    function.json file open in Visual Studio for mac

  4. 솔루션 창에서 AzureFunctionsLab 프로젝트 노드를 마우스 오른쪽 단추로 클릭하고 추가 > 새 폴더를 선택합니다. 새 폴더 이름을 Adder로 지정합니다. 기본 규칙에서 이 폴더의 이름은 api/Adder처럼 API에 대한 경로를 정의합니다.

    New folder option

  5. Adder 폴더를 마우스 오른쪽 단추로 클릭하고 추가 > 새 파일을 선택합니다.

    New file option

  6. 범주 및 빈 JSON 파일 템플릿을 선택합니다. 이름function으로 설정하고 새로 만들기를 클릭합니다.

    Empty json file option

  7. 다른 function.json의 콘텐츠(3단계)를 붙여 넣어 새로 만든 파일의 기본 콘텐츠를 변경합니다.

  8. json 파일의 위쪽에서 다음 줄을 제거합니다.

    "configurationSource":"attributes",
    "generatedBy":"Microsoft.NET.Sdk.Functions-1.0.13",
    
  9. 첫 번째 바인딩의 끝에 ("name": "req" 줄 뒤) 다음 속성을 추가합니다. 앞줄에 쉼표를 포함해야 합니다. 이 속성은 이제 기본 경로를 재정의하며 경로에서 int 매개 변수를 추출하여 이름이 xy인 메서드 매개 변수에 배치합니다.

    "direction": "in",
    "route": "Adder/{x:int?}/{y:int?}"
    
  10. 첫 번째 아래 다른 바인딩을 추가합니다. 이 바인딩은 함수의 반환 값을 처리합니다. 앞줄에 쉼표를 포함해야 합니다.

    {
    "name": "$return",
    "type": "http",
    "direction": "out"
    }
    
  11. 파일 맨 아래의 entryPoint 속성을 아래처럼 "Add2"라는 메서드를 사용하도록 업데이트합니다. 이것은 api/Adder... 경로가 모든 이름(여기서는 Add2)의 적합한 메서드에 매핑할 수 있음을 설명하기 위한 것입니다.

    "entryPoint": "<project-name>.<function-class-name>.Add2"
    
  12. 최종 function.json 파일은 다음 json과 비슷합니다.

    {
    "bindings": [
        {
        "type": "httpTrigger",
        "methods": [
            "get"
        ],
        "authLevel": "function",
        "direction": "in",
        "name": "req",
        "route": "Adder/{x:int?}/{y:int?}"
        },
        {
        "name": "$return",
        "type": "http",
        "direction": "out"
        }
    ],
    "disabled": false,
    "scriptFile": "../bin/AzureFunctionsProject.dll",
    "entryPoint": "AzureFunctionsProject.Add.Add2"
    }
    
  13. 이것이 제대로 작동하기 위해 필요한 마지막 단계는 Mac용 Visual Studio에게 이 파일이 바뀔 때마다 출력 디렉터리의 동일한 상대 경로에 해당 파일을 복사하도록 지시하는 것입니다. 파일을 선택한 상태에서 오른쪽 표시줄에 있는 속성 탭을 선택하고 출력 디렉터리에 복사에서 변경된 내용만 복사를 선택합니다.

    Properties options for json file

  14. 예상되는 기능을 수행할 수 있게 Add.cs에서 Run 메서드(특성 포함)를 다음 메서드로 바꿉니다. 특성을 사용하지 않으며 xy에 대한 명시적 매개 변수가 있다는 점을 제외하고 Run과 매우 유사합니다.

    public static int Add2(
        HttpRequestMessage req,
        int x,
        int y,
        TraceWriter log)
    {
        return x + y;
    }
    
  15. F5를 눌러 프로젝트를 빌드하고 실행합니다.

  16. 빌드가 완료되고 플랫폼이 작동을 시작했으므로 이제 새로 추가된 메서드에 매핑되는 요청에 사용할 수 있는 두 번째 경로가 있음을 표시합니다.

    URL for HTTP functions

  17. 브라우저 창으로 돌아와 http://localhost:7071/api/Adder/3/5로 이동합니다.

  18. 이번에는 메서드가 다시 한 번 경로에서 매개 변수를 가져오고 합계를 생성합니다.

  19. Mac용 Visual Studio로 돌아와 디버깅 세션을 종료합니다.

연습 5: Azure Storage 테이블 작업

빌드하는 서비스는 지금까지 빌드한 서비스보다 훨씬 더 복잡할 수 있으며 실행하는 데 상당한 시간 또는 인프라가 필요할 수 있습니다. 이 경우 리소스가 사용 가능하게 될 때 처리 대기 중인 요청을 수락하도록 하는 것이 효과적일 수 있으며 Azure Functions에서 이를 지원합니다. 다른 경우에는 데이터를 중앙에 저장하려고 합니다. Azure Storage 테이블에서는 이를 신속하게 수행할 수 있습니다.

  1. 다음 클래스를 Add.cs 추가합니다. 네임스페이스 내부이면서 기존 클래스의 외부에 있어야 합니다.

    public class TableRow : TableEntity
    {
        public int X { get; set; }
        public int Y { get; set; }
        public int Sum { get; set; }
    }
    
  2. Add 클래스 내에서 다음 코드를 추가하여 다른 함수를 도입합니다. 이 함수는 지금까지 고유하므로 HTTP 응답을 포함하지 않습니다. 마지막 줄은 나중에 검색하기 쉽게 일부 키 정보(PartitionKeyRowKey)가 입력된 새 TableRow와 해당 매개 변수 및 합계를 반환합니다. 메서드의 코드는 또한 사용 하 여는 TraceWriter 쉽게 함수 실행 하는 경우에 대해 알아야 합니다.

    [FunctionName("Process")]
    [return: Table("Results")]
    public static TableRow Process(
        [HttpTrigger(AuthorizationLevel.Function, "get",
            Route = "Process/{x:int}/{y:int}")]
        HttpRequestMessage req,
        int x,
        int y,
        TraceWriter log)
    {
        log.Info($"Processing {x} + {y}");
    
        return new TableRow()
        {
            PartitionKey = "sums",
            RowKey = $"{x}_{y}",
            X = x,
            Y = y,
            Sum = x + y
        };
    }
    
  3. F5를 눌러 프로젝트를 빌드하고 실행합니다.

  4. 브라우저 탭에서 http://localhost:7071/api/Process/4/6로 이동합니다. 그러면 큐에 다른 메시지가 추가되고 이에 따라 테이블에 다른 행이 추가됩니다.

  5. 터미널로 돌아와 4 + 6을 위한 수신 요청을 찾아봅니다.

    Terminal output showing addition request

  6. 브라우저로 돌아와 같은 URL에 대한 요청을 새로 고칩니다. 이제 Process 메서드 다음에 오류가 표시됩니다. 이 코드가 이미 존재하는 파티션과 행 키 조합을 사용하는 Azure Table Storage 테이블에 행을 추가하려 시도하기 때문입니다.

    System.Private.CoreLib: Exception while executing function: Process. Microsoft.Azure.WebJobs.Host: Error while handling parameter $return after function returned:. Microsoft.Azure.WebJobs.Host: The specified entity already exists.

  7. 디버깅 세션을 종료합니다.

  8. 오류를 해결하려면 다음 매개 변수를 TraceWriter 매개 변수 바로 앞의 메서드 정의에 추가합니다. 이 매개 변수는 Azure Functions에게 결과를 저장하는 데 사용한 PartitionKeyResults에서 TableRow을 검색하도록 지시합니다. 그러나 여기서 놀라운 사실은 RowKey는 같은 메서드에 대한 다른 xy 매개 변수를 기준으로 동적으로 생성된다는 점입니다. 행이 이미 있을 경우 개발자의 추가적인 작업 없이도 메서드가 시작될 때 tableRow에 해당 행이 있게 됩니다. 행이 없으면 null뿐입니다. 이러한 종류의 효율성을 통해 개발자는 인프라가 아닌 중요한 비즈니스 논리에 집중할 수 있습니다.

    [Table("Results", "sums", "{x}_{y}")]
    TableRow tableRow,
    
  9. 메서드의 시작 부분에 다음 코드를 추가합니다. tableRow이 null이 아니라면 요청된 작업에 대한 결과가 이미 있고 즉시 반환할 수 있습니다. 그렇지 않으면 함수는 전과 같이 진행됩니다. 데이터를 반환하는 가장 강력한 방법은 아니지만 코드가 거의 없는 여러 확장 가능한 계층에서 매우 정교한 작업을 오케스트레이션할 수 있다는 점을 보여 줍니다.

    if (tableRow != null)
    {
        log.Info($"{x} + {y} already exists");
        return null;
    }
    
  10. F5를 눌러 프로젝트를 빌드하고 실행합니다.

  11. 브라우저 탭에서 http://localhost:7071/api/Process/4/6의 URL을 새로 고칩니다. 이 레코드에 대한 테이블 행이 있으므로 즉시 오류 없이 반환할 것입니다. HTTP 출력이 없으므로 터미널에서 출력을 확인할 수 있습니다.

    Terminal output showing table row already exists

  12. URL을 업데이트하여 아직 테스트하지 않은 조합을 반영합니다(예: http://localhost:7071/api/Process/5/7). 테이블 행이 없음을 표시하는(예상한 대로) 터미널의 메시지를 확인합니다.

    Terminal output showing new process

  13. Mac용 Visual Studio로 돌아와 디버깅 세션을 종료합니다.

요약

이 연습에서는 Mac용 Visual Studio를 사용하여 Azure Functions 빌드를 시작하는 방법을 살펴보았습니다.