Azure Functions 및 API Management 통합을 사용하여 Visual Studio에서 서버리스 API 만들기

REST API는 종종 OpenAPI 정의를 사용하여 설명됩니다. 이 파일에는 API의 작업과 API에 대한 요청 및 응답 데이터를 구성하는 방법에 대한 정보가 포함되어 있습니다.

이 자습서에서는 다음을 하는 방법을 알아볼 수 있습니다.

  • Visual Studio에서 서버리스 함수 프로젝트 만들기
  • 기본 제공 OpenAPI 기능을 사용하여 함수 API를 로컬로 테스트
  • API Management 통합을 사용하여 Azure에서 함수 앱에 프로젝트 게시
  • 함수에 대한 액세스 키를 가져와 API Management에 설정
  • OpenAPI 정의 파일 다운로드

사용자가 만든 서버리스 함수는 윈드 터빈의 응급 복구가 비용 효율적인지 여부를 확인할 수 있는 API를 제공합니다. 만든 함수 앱과 API Management 인스턴스는 모두 사용 계획을 사용하기 때문에 이 자습서를 완료하는 데 드는 비용이 최소화됩니다.

참고 항목

이 문서에 소개된 OpenAPI 및 API Management 통합은 현재 In-process C# 클래스 라이브러리 함수에 대해서만 지원됩니다. 격리된 작업자 프로세스 C# 클래스 라이브러리 함수 및 기타 모든 언어 런타임은 포털에서 Azure API Management 통합을 대신 사용해야 합니다.

필수 조건

Functions 프로젝트 만들기

Visual Studio의 Azure Functions 프로젝트 템플릿은 Azure에서 함수 앱에 게시할 수 있는 프로젝트를 만듭니다. 또한 OpenAPI 정의 파일(이전의 Swagger 파일) 생성을 지원하는 HTTP 트리거 함수를 만듭니다.

  1. Visual Studio 메뉴에서 파일>새로 만들기>프로젝트를 차례로 선택합니다.

  2. 새 프로젝트 만들기에서 검색 상자에 함수를 입력하고, Azure Functions 템플릿을 선택한 다음, 다음을 선택합니다.

  3. 새 프로젝트 구성에서 TurbineRepair와 같이 프로젝트에 대한 프로젝트 이름을 입력한 다음, 만들기를 선택합니다.

  4. 새 Azure Functions 애플리케이션 만들기 설정에 대해서는 다음 표의 값을 사용합니다.

    설정 설명
    Functions 작업자 .NET 6 이 값은 OpenAPI 파일 생성에 필요한 Azure Functions 런타임 버전 4.x에서 in-process를 실행하는 함수 프로젝트를 만듭니다.
    함수 템플릿 OpenAPI를 사용하는 HTTP 트리거 이 값은 OpenAPI 정의 파일을 생성하는 기능을 사용하여 HTTP 요청에 의해 트리거되는 함수를 만듭니다.
    런타임 스토리지 계정(AzureWebJobsStorage)에 Azurite 사용 Selected HTTP 트리거 함수의 로컬 개발에 에뮬레이터를 사용할 수 있습니다. Azure의 함수 앱에는 스토리지 계정이 필요하기 때문에 Azure에 프로젝트를 게시할 때 할당되거나 생성됩니다.
    권한 부여 수준 Function Azure에서 실행하는 경우 클라이언트는 엔드포인트에 액세스할 때 키를 제공해야 합니다. 키 및 권한 부여에 대한 자세한 내용은 함수 액세스 키를 참조하세요.

    Azure Functions project settings

  5. OpenAPI를 지원하는 함수 프로젝트 및 HTTP 트리거 함수를 만들려면 만들기를 선택합니다.

Visual Studio는 HTTP 트리거 함수 형식에 대한 상용구 코드가 포함된 프로젝트와 Function1이라는 클래스를 만듭니다. 다음으로, 이 함수 템플릿 코드를 사용자 지정 코드로 대체합니다.

함수 코드 업데이트

이 함수는 두 개의 매개 변수를 사용하는 HTTP 트리거를 사용합니다.

매개 변수 이름 설명
시간 터빈을 복구하는 데 예상되는 시간(최대 1시간)입니다.
capacity 터빈 용량(킬로와트)

그런 다음, 함수는 복구 비용과 터빈이 24시간 내에 가져올 수 있는 수익을 계산합니다. 매개 변수는 쿼리 문자열 또는 POST 요청의 페이로드에서 제공됩니다.

Function1.cs 프로젝트 파일에서 생성된 클래스 라이브러리 코드의 내용을 다음 코드로 대체합니다.

using System;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Attributes;
using Microsoft.Azure.WebJobs.Extensions.OpenApi.Core.Enums;
using Microsoft.Extensions.Logging;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;

namespace TurbineRepair
{
    public static class Turbines
    {
        const double revenuePerkW = 0.12;
        const double technicianCost = 250;
        const double turbineCost = 100;

        [FunctionName("TurbineRepair")]
        [OpenApiOperation(operationId: "Run")]
        [OpenApiSecurity("function_key", SecuritySchemeType.ApiKey, Name = "code", In = OpenApiSecurityLocationType.Query)]
        [OpenApiRequestBody("application/json", typeof(RequestBodyModel), 
            Description = "JSON request body containing { hours, capacity}")]
        [OpenApiResponseWithBody(statusCode: HttpStatusCode.OK, contentType: "application/json", bodyType: typeof(string),
            Description = "The OK response message containing a JSON result.")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            // Get request body data.
            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            int? capacity = data?.capacity;
            int? hours = data?.hours;

            // Return bad request if capacity or hours are not passed in
            if (capacity == null || hours == null)
            {
                return new BadRequestObjectResult("Please pass capacity and hours in the request body");
            }
            // Formulas to calculate revenue and cost
            double? revenueOpportunity = capacity * revenuePerkW * 24;
            double? costToFix = (hours * technicianCost) + turbineCost;
            string repairTurbine;

            if (revenueOpportunity > costToFix)
            {
                repairTurbine = "Yes";
            }
            else
            {
                repairTurbine = "No";
            };

            return (ActionResult)new OkObjectResult(new
            {
                message = repairTurbine,
                revenueOpportunity = "$" + revenueOpportunity,
                costToFix = "$" + costToFix
            });
        }
    }
    public class RequestBodyModel
    {
        public int Hours { get; set; }
        public int Capacity { get; set; } 
    }
}

이 함수 코드는 Yes 또는 No의 메시지를 반환하여 응급 복구가 비용 효율적인지 여부를 나타냅니다. 또한 터빈이 나타내는 수익 기회와 터빈 수정에 드는 비용을 반환합니다.

API를 로컬로 실행 및 확인

함수를 실행할 때 OpenAPI 엔드포인트를 사용하면 생성된 페이지를 사용하여 로컬에서 함수를 쉽게 사용해 볼 수 있습니다. 로컬로 실행할 때 함수 액세스 키를 제공할 필요가 없습니다.

  1. F5 키를 눌러 프로젝트를 시작합니다. Functions 런타임이 로컬로 시작되면 OpenAPI 및 Swagger 엔드포인트 집합이 함수 엔드포인트와 함께 출력에 표시됩니다.

  2. 브라우저에서 RenderSwaggerUI 엔드포인트를 열면 http://localhost:7071/api/swagger/ui와 같이 표시됩니다. 페이지는 OpenAPI 정의에 따라 렌더링됩니다.

  3. POST>사용해 보기를 선택하고, hourscapacity에 대한 값을 쿼리 매개 변수로 입력하거나 JSON 요청 본문에서 입력하고, 실행을 선택합니다.

    Swagger UI for testing the TurbineRepair API

  4. hours에 6, capacity에 2500과 같은 정수 값을 입력하면 다음 예와 같은 JSON 응답을 받게 됩니다.

    Response JSON data from the TurbineRepair function.

이제 응급 복구 작업의 비용 효율성을 결정하는 함수가 만들어졌습니다. 그런 다음 프로젝트 및 API 정의를 Azure에 게시합니다.

Azure에 프로젝트 게시

프로젝트를 게시하려면 먼저 Azure 구독에 함수 앱이 있어야 합니다. 프로젝트를 처음 게시할 때 Visual Studio 게시에서 함수 앱을 만듭니다. TurbineRepair API를 노출하기 위해 함수 앱과 통합되는 API Management 인스턴스를 만들 수도 있습니다.

  1. 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 게시를 선택하고 대상에서 Azure를 선택한 다음, 다음을 선택합니다.

  2. 특정 대상의 경우 Windows에서 실행되는 함수 앱을 만드는 Azure 함수 앱(Windows)을 선택 후, 다음을 선택합니다.

  3. 함수 인스턴스에서 + 새 Azure 함수 만들기...를 선택합니다.

    Create a new function app instance

  4. 다음 표에 지정된 값을 사용하여 새 인스턴스를 만듭니다.

    설정 설명
    이름 전역적으로 고유한 이름 새 함수 앱을 고유하게 식별하는 이름입니다. 이 이름을 수락하거나 새 이름을 입력합니다. 유효한 문자는 a-z, 0-9-입니다.
    구독 구독 사용할 Azure 구독입니다. 이 구독을 수락하거나 드롭다운 목록에서 새 구독을 선택합니다.
    리소스 그룹 리소스 그룹의 이름 함수 앱을 만들 리소스 그룹입니다. 드롭다운 목록에서 기존 리소스 그룹을 선택하거나 새로 만들기를 선택하여 새 리소스 그룹을 만듭니다.
    계획 유형 Consumption 프로젝트를 사용량 요금제에서 실행되는 함수 앱에 게시하는 경우 함수 앱의 실행에 대한 비용만 지불합니다. 다른 호스팅 계획에는 비용이 더 많이 듭니다.
    위치 서비스의 위치 사용자 또는 함수가 액세스하는 기타 서비스에 가까운 지역위치를 선택합니다.
    Azure Storage 범용 스토리지 계정 Functions 런타임에는 Azure Storage 계정이 필요합니다. 새로 만들기를 선택하여 범용 스토리지 계정을 구성합니다. 스토리지 계정 요구 사항을 충족하는 기존 계정을 선택할 수도 있습니다.

    Create a new function app in Azure with Storage

  5. 만들기를 선택하여 Azure에서 함수 앱 및 관련된 리소스를 만듭니다. 리소스 만들기 상태는 창의 왼쪽 하단에 표시됩니다.

  6. 함수 인스턴스로 돌아가서 패키지 파일에서 실행이 선택되어 있는지 확인합니다. Run-From-Package 모드를 사용하도록 설정된 상태에서 Zip 배포를 사용하여 함수 앱이 배포됩니다. 이 배포 방법은 성능이 향상되므로 함수 프로젝트에 권장됩니다.

  7. 다음을 선택하고 API Management 페이지에서 + API Management API 만들기를 선택합니다.

  8. 다음 표의 값을 사용하여 API Management에서 API를 만듭니다.

    설정 설명
    API 이름 TurbineRepair API의 이름입니다.
    구독 이름 구독 사용할 Azure 구독입니다. 이 구독을 수락하거나 드롭다운 목록에서 새 구독을 선택합니다.
    리소스 그룹 리소스 그룹의 이름 드롭다운 목록에서 함수 앱과 동일한 리소스 그룹을 선택합니다.
    API Management 서비스 새 인스턴스 서버리스 계층에 새 API Management 인스턴스를 만들려면 새로 만들기를 선택합니다.

    Create API Management instance with API

  9. 함수 통합에서 TurbineRepair API로 API Management 인스턴스를 만들려면 만들기를 선택합니다.

  10. 마침을 선택하고 게시 페이지에 게시 준비라고 표시되는지 확인하고, 게시를 선택하여 프로젝트 파일이 포함된 패키지를 Azure의 새 함수 앱에 배포합니다.

    배포가 완료되면 Azure에서 함수 앱의 루트 URL이 게시 탭에 표시됩니다.

함수 액세스 키 가져오기

  1. 게시 탭에서 호스팅 옆에 있는 줄임표(...)를 선택하고 Azure Portal에서 열기를 선택합니다. 만들어진 함수 앱이 기본 브라우저의 Azure Portal에서 열립니다.

  2. Functions에서 Functions>TurbineRepair를 선택한 다음 함수 키를 선택합니다.

    Get an access key for the TurbineRepair function

  3. 함수 키에서 기본값을 선택하고 을 복사합니다. 이제 함수 엔드포인트에 액세스할 수 있도록 API Management에 이 키를 설정할 수 있습니다.

API Management 구성

  1. 게시 탭에서 호스팅 옆에 있는 줄임표(...)를 선택하고 Azure Portal에서 API 열기를 선택합니다. 만들어진 API Management 인스턴스가 기본 브라우저의 Azure Portal에서 열립니다. 이 API Management 인스턴스는 함수 앱에 이미 연결되어 있습니다.

  2. API에서 Azure Functions의 OpenAPI 문서>POST 실행을 선택한 다음, 인바운드 처리에서 정책 추가를 선택합니다.

    Add an inbound policy to the API

  3. 인바운드 처리 아래의 쿼리 매개 변수 설정에서 이름code를 입력하고, +값을 선택하고, 복사한 함수 키를 붙여넣고, 저장을 선택합니다. API Management에서 호출을 함수 엔드포인트에 전달하는 경우 함수 키가 포함됩니다.

    Provide Function credentials to the API inbound processing rule

이제 함수 키가 설정되면 API를 호출하여 Azure에서 호스트할 때 작동하는지 확인할 수 있습니다.

Azure에서 API 확인

  1. API에서 테스트 탭, POST 실행을 차례로 선택하고, 요청 본문>원시에 다음 코드를 입력하고, 보내기를 선택합니다.

    {
        "hours": "6",
        "capacity": "2500"
    }
    

    OpenAPI test page in the API Management API

    이전과 마찬가지로 쿼리 매개 변수와 동일한 값을 제공할 수도 있습니다.

  2. 보내기를 선택한 다음 HTTP 응답을 확인하여 API에서 동일한 결과가 반환되는지 확인합니다.

OpenAPI 정의 다운로드

API가 예상대로 작동하는 경우 OpenAPI 정의를 다운로드할 수 있습니다.

    1. API에서 Azure Functions에 대한 OpenAPI 문서를 선택하고, 줄임표(...)를 선택하고, 내보내기를 선택합니다.

    Download OpenAPI definition

  1. 다양한 형식의 OpenAPI 파일을 포함하여 API 내보내기 방법을 선택합니다. Azure API Management에서 Power Platform으로 API를 내보낼 수도 있습니다.

리소스 정리

이전 단계에서는 리소스 그룹에서 Azure 리소스를 만들었습니다. 나중에 이러한 리소스가 필요하지 않은 경우에 리소스 그룹을 삭제하여 삭제할 수 있습니다.

Azure Portal 메뉴 또는 페이지에서 리소스 그룹을 선택합니다. 그런 다음 리소스 그룹 페이지에서 만든 그룹을 선택합니다.

myResourceGroup 페이지에서 나열된 리소스가 삭제하려는 리소스인지 확인합니다.

리소스 그룹 삭제를 선택하고, 텍스트 상자에서 그룹 이름을 입력하여 확인한 다음, 삭제를 선택합니다.

다음 단계

Visual Studio 2022를 사용하여 OpenAPI 확장으로 인해 자체 문서화되고 API Management와 통합되는 함수를 만들었습니다. 이제 포털의 API Management에서 정의를 구체화할 수 있습니다. 또한 API Management에 대해 자세히 알아볼 수 있습니다.