자습서: Azure Static Web Apps에서 Azure Cosmos DB 데이터베이스 연결 추가(미리 보기)

이 자습서에서는 NoSQL용 Azure Cosmos DB 데이터베이스를 정적 웹앱에 연결하는 방법을 알아봅니다. 구성되면 백 엔드 코드를 작성하지 않고도 기본 제공 엔드포인트에 /data-api 대한 GraphQL 요청을 만들어 데이터를 조작할 수 있습니다.

간단히 하기 위해 이 자습서에서는 로컬 개발 목적으로 Azure 데이터베이스를 사용하는 방법을 보여 주지만 로컬 개발 요구 사항에 맞게 로컬 데이터베이스 서버를 사용할 수도 있습니다.

참고 항목

이 자습서에서는 NoSQL용 Azure Cosmos DB를 사용하는 방법을 보여 줍니다. 다른 데이터베이스를 사용하려면 Azure SQL, MySQL 또는 PostgreSQL 자습서를 참조하세요.

Web browser showing results from Cosmos DB in the developer tools console window.

이 자습서에서는 다음을 알아봅니다.

  • NoSQL용 Azure Cosmos DB 데이터베이스를 정적 웹앱에 연결
  • 데이터의 만들기, 읽기, 업데이트 및 삭제

필수 조건

이 자습서를 완료하려면 기존 Azure Cosmos DB for NoSQL 데이터베이스 및 정적 웹앱이 있어야 합니다.

리소스 설명
NoSQL 데이터베이스용 Azure Cosmos DB 아직 없는 경우 Azure Cosmos DB 데이터베이스 만들기 가이드의 단계를 따릅니다.
기존 정적 웹앱 아직 없는 경우 시작 가이드의 단계에 따라 No Framework 정적 웹앱을 만듭니 다.

먼저 Azure Static Web Apps 데이터베이스 연결 기능을 사용하도록 데이터베이스를 구성합니다.

데이터베이스 연결 구성

azure Static Web Apps는 데이터베이스 연결 작동하려면 데이터베이스에 대한 네트워크 액세스 권한이 있어야 합니다. 또한 로컬 개발에 Azure 데이터베이스를 사용하려면 자체 IP 주소의 요청을 허용하도록 데이터베이스를 구성해야 합니다.

  1. Azure Portal에서 NoSQL용 Azure Cosmos DB 계정으로 이동합니다.

  2. 설정 섹션에서 네트워킹을 선택합니다.

  3. 공용 액세스 섹션에서 모든 네트워크를 선택합니다. 이 작업을 통해 로컬 개발에 클라우드 데이터베이스를 사용하고, 배포된 Static Web Apps 리소스가 데이터베이스에 액세스할 수 있으며, 포털에서 데이터베이스를 쿼리할 수 있습니다.

  4. 저장을 선택합니다.

로컬 개발을 위한 데이터베이스 연결 문자열 가져오기

로컬 개발에 Azure 데이터베이스를 사용하려면 데이터베이스의 연결 문자열 검색해야 합니다. 개발 목적으로 로컬 데이터베이스를 사용하려는 경우 이 단계를 건너뛸 수 있습니다.

  1. Azure Portal에서 NoSQL용 Azure Cosmos DB 계정으로 이동합니다.

  2. 설정 섹션에서 키를 선택합니다.

  3. 기본 연결 문자열 상자에서 연결 문자열 복사하고 텍스트 편집기에서 따로 설정합니다.

샘플 데이터 만들기

샘플 테이블을 만들고 샘플 데이터로 시드하여 자습서와 일치합니다.

  1. 왼쪽 탐색 창에서 데이터 탐색기를 선택합니다.

  2. 새 컨테이너를 선택합니다. 데이터베이스 ID를 로 Create new입력하고 값으로 입력 MyTestPersonDatabase 합니다.

  3. 의 컨테이너 ID를 입력합니다 MyTestPersonContainer.

  4. 파티션 키를 id 입력합니다(이 값의 접두사는 접두사 /).

  5. 확인을 선택합니다.

  6. MyTestPersonContainer 컨테이너를 선택합니다.

  7. 해당 항목을 선택합니다.

  8. 새 항목을 선택하고 다음 값을 입력합니다.

    {
        "id": "1",
        "Name": "Sunny"
    }
    

정적 웹앱 구성

이 자습서의 나머지 내용은 로컬에서 데이터베이스 연결 사용하도록 정적 웹앱의 소스 코드를 편집하는 데 중점을 둡니다.

Important

다음 단계에서는 시작 가이드에서 만든 정적 웹앱으로 작업하고 있다고 가정합니다. 다른 프로젝트를 사용하는 경우 다음 git 명령을 분기 이름과 일치하도록 조정해야 합니다.

  1. main 분기로 전환합니다.

    git checkout main
    
  2. 를 사용하여 git pull로컬 버전을 GitHub의 버전과 동기화합니다.

    git pull origin main
    

데이터베이스 구성 파일 만들기

다음으로, 정적 웹앱이 데이터베이스와 인터페이스하는 데 사용하는 구성 파일을 만듭니다.

  1. 터미널을 열고 연결 문자열 저장할 새 변수를 만듭니다. 특정 구문은 사용 중인 셸 유형에 따라 달라질 수 있습니다.

    export DATABASE_CONNECTION_STRING='<YOUR_CONNECTION_STRING>'
    

    텍스트 편집기에서 따로 설정한 연결 문자열 값으로 바꿔 <YOUR_CONNECTION_STRING> 야 합니다.

  2. npm을 사용하여 Static Web Apps CLI를 설치하거나 업데이트합니다. 상황에 가장 적합한 명령을 선택합니다.

    설치 npm install하려면 .

    npm install -g @azure/static-web-apps-cli
    

    업데이트 npm update하려면 .

    npm update
    
  3. swa db init 명령을 사용하여 데이터베이스 구성 파일을 생성합니다.

    swa db init --database-type cosmosdb_nosql --cosmosdb_nosql-database MyTestPersonDatabase
    

    init 명령은 swa-db-connections 폴더에 staticwebapp.database.config.json 파일을 만듭니다.

  4. 이 샘플 스키마를 생성한 staticwebapp.database.schema.gql 파일에 붙여넣습니다.

    NoSQL용 Cosmos DB는 스키마에 구애받지 않는 데이터베이스이므로 Azure Static Web Apps 데이터베이스 연결 데이터베이스의 스키마를 추출할 수 없습니다. staticwebapp.database.schema.gql 파일을 사용하면 Static Web Apps용 NoSQL용 Cosmos DB 데이터베이스의 스키마를 지정할 수 있습니다.

    type Person @model {
      id: ID
      Name: String
    }
    
  5. 이 샘플 구성을 생성한 staticwebapp.database.config.json 파일에 붙여넣습니다. NoSQL용 Cosmos DB에는 Cosmos DB 데이터베이스 및 데이터베이스의 스키마를 이해하는 데 데이터베이스 연결 데 필요한 스키마 파일을 나타내는 더 많은 옵션이 data-source 개체에 있습니다.

{
  "$schema": "https://github.com/Azure/data-api-builder/releases/latest/download/dab.draft.schema.json",
  "data-source": {
    "database-type": "cosmosdb_nosql",
    "options": {
      "database": "MyTestPersonDatabase",
      "schema": "staticwebapp.database.schema.gql"
    },
    "connection-string": "@env('DATABASE_CONNECTION_STRING')"
  },
  "runtime": {
    "graphql": {
      "allow-introspection": true,
      "enabled": true,
      "path": "/graphql"
    },
    "host": {
      "mode": "production",
      "cors": {
        "origins": ["http://localhost:4280"],
        "allow-credentials": false
      },
      "authentication": {
        "provider": "StaticWebApps"
      }
    }
  },
  "entities": {
    "Person": {
      "source": "MyTestPersonContainer",
      "permissions": [
        {
          "actions": ["*"],
          "role": "anonymous"
        }
      ]
    }
  }
}

다음 단계로 이동하기 전에 구성 파일의 다양한 측면을 설명하는 다음 표를 검토합니다. 구성 파일 및 항목 수준 보안에 대한 관계 및 정책과 같은 기능에 대한 전체 설명서는 Data API Builder 설명서를 참조 하세요.

기능 설명
데이터베이스 연결 개발 시 런타임은 구성 파일의 연결 문자열 값에서 연결 문자열 읽습니다. 구성 파일에서 직접 연결 문자열 지정할 수 있지만 연결 문자열 로컬 환경 변수에 저장하는 것이 가장 좋습니다. 표기법을 통해 구성 파일에서 환경 변수 값을 참조할 @env('DATABASE_CONNECTION_STRING') 수 있습니다. 데이터베이스를 연결할 때 수집된 정보를 사용하여 배포된 사이트에 대한 Static Web Apps에서 연결 문자열 값을 덮어씁니다.
API 엔드포인트 GraphQL 엔드포인트는 이 구성 파일에 구성된 대로 사용할 수 있습니다 /data-api/graphql . GraphQL 경로를 구성할 수 있지만 접두사는 /data-api 구성할 수 없습니다.
API 보안 설정을 runtime.host.cors 사용하면 API에 요청할 수 있는 허용된 원본을 정의할 수 있습니다. 이 경우 구성은 개발 환경을 반영하고 위치를 허용 목록에 추가합니다 http://localhost:4280 .
엔터티 모델 경로를 통해 노출되는 엔터티를 GraphQL 스키마의 형식으로 정의합니다. 이 경우 Person이라는 이름은 데이터베이스 스키마 및 테이블 매핑인 동안 entities.<NAME>.source 엔드포인트에 노출되는 이름입니다. API 엔드포인트 이름이 테이블 이름과 동일할 필요가 없는 방법을 확인합니다.
엔터티 보안 배열에 entity.<NAME>.permissions 나열된 권한 규칙은 엔터티에 대한 권한 부여 설정을 제어합니다. 역할을 사용하여 경로를 보호하는 것과 동일한 방식으로 역할을 사용하여 엔터티를 보호할 수 있습니다.

참고 항목

구성 파일 및 connection-stringhost.modegraphql.allow-introspection 속성은 사이트를 배포할 때 덮어씁니다. 데이터베이스를 Static Web Apps 리소스에 연결할 때 수집된 인증 세부 정보로 연결 문자열 덮어씁니다. 속성이 host.modeproduction설정되고 이 속성은 graphql.allow-introspection .로 false설정됩니다. 이러한 재정의는 개발 및 프로덕션 워크로드에서 구성 파일의 일관성을 제공하는 동시에 데이터베이스 연결 사용하도록 설정된 Static Web Apps 리소스가 안전하고 프로덕션 준비가 되도록 합니다.

데이터베이스에 연결하도록 구성된 정적 웹앱을 사용하여 이제 연결을 확인할 수 있습니다.

홈페이지 업데이트

index.html 파일의 body 태그 간 태그를 다음 HTML로 바꿉니다.

<h1>Static Web Apps Database Connections</h1>
<blockquote>
    Open the console in the browser developer tools to see the API responses.
</blockquote>
<div>
    <button id="list" onclick="list()">List</button>
    <button id="get" onclick="get()">Get</button>
    <button id="update" onclick="update()">Update</button>
    <button id="create" onclick="create()">Create</button>
    <button id="delete" onclick="del()">Delete</button>
</div>
<script>
    // add JavaScript here
</script>

로컬로 애플리케이션 시작

이제 웹 사이트를 실행하고 데이터베이스의 데이터를 직접 조작할 수 있습니다.

  1. npm을 사용하여 Static Web Apps CLI를 설치하거나 업데이트합니다. 상황에 가장 적합한 명령을 선택합니다.

    설치 npm install하려면 .

    npm install -g @azure/static-web-apps-cli
    

    업데이트 npm update하려면 .

    npm update
    
  2. 데이터베이스 구성을 사용하여 정적 웹앱을 시작합니다.

    swa start ./src --data-api-location swa-db-connections
    

CLI가 시작되었으므로 staticwebapp.database.config.json 파일에 정의된 대로 엔드포인트를 통해 데이터베이스에 액세스할 수 있습니다.

엔드포인트는 http://localhost:4280/data-api/graphql GraphQL 쿼리 및 변형을 허용합니다.

데이터 조작

다음 프레임워크에 구애받지 않는 명령은 데이터베이스에서 전체 CRUD 작업을 수행하는 방법을 보여 줍니다.

각 함수의 출력이 브라우저의 콘솔 창에 나타납니다.

CMD/Ctrl + Shift + I를 눌러 개발자 도구를 열고 콘솔 탭을 선택합니다.

모든 항목 나열

index.html 태그 사이에 script 다음 코드를 추가합니다.

async function list() {

  const query = `
      {
        people {
          items {
            id
            Name
          }
        }
      }`;
      
  const endpoint = "/data-api/graphql";
  const response = await fetch(endpoint, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ query: query })
  });
  const result = await response.json();
  console.table(result.data.people.items);
}

이 예에서는 다음이 적용됩니다.

  • GraphQL 쿼리는 데이터베이스에서 Id 필드와 Name 필드를 선택합니다.
  • 서버에 전달된 요청에는 속성에 쿼리 정의가 query 있는 페이로드가 필요합니다.
  • 응답 페이로드의 데이터는 속성에 data.people.items 있습니다.

페이지를 새로 고치고 목록 단추를 선택합니다.

이제 브라우저의 콘솔 창에 데이터베이스의 모든 레코드를 나열하는 테이블이 표시됩니다.

id 속성
1 맑음
2 데에라즈 주

브라우저에서 어떻게 표시되어야 하는지에 대한 스크린샷은 다음과 같습니다.

Web browser showing results from a database selection in the developer tools console window.

ID로 가져오기

index.html 태그 사이에 script 다음 코드를 추가합니다.

async function get() {

  const id = '1';

  const gql = `
    query getById($id: ID!) {
      person_by_pk(id: $id) {
        id
        Name
      }
    }`;

  const query = {
    query: gql,
    variables: {
      id: id,
    },
  };

  const endpoint = "/data-api/graphql";
  const response = await fetch(endpoint, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(query),
  });
  const result = await response.json();
  console.table(result.data.person_by_pk);
}

이 예에서는 다음이 적용됩니다.

  • GraphQL 쿼리는 데이터베이스에서 id 필드와 Name 필드를 선택합니다.
  • 서버에 전달된 요청에는 속성에 쿼리 정의가 query 있는 페이로드가 필요합니다.
  • 응답 페이로드의 데이터는 속성에 data.person_by_pk 있습니다.

페이지를 새로 고치고 가져오기 단추를 선택합니다.

이제 브라우저의 콘솔 창에 데이터베이스에서 요청된 단일 레코드가 나열된 테이블이 표시됩니다.

id 속성
1 맑음

엽데이트

index.html 태그 사이에 script 다음 코드를 추가합니다.

async function update() {

  const id = '1';
  const data = {
    id: id,
    Name: "Molly"
  };

  const gql = `
    mutation update($id: ID!, $_partitionKeyValue: String!, $item: UpdatePersonInput!) {
      updatePerson(id: $id, _partitionKeyValue: $_partitionKeyValue, item: $item) {
        id
        Name
      }
    }`;

  const query = {
    query: gql,
    variables: {
      id: id,
      _partitionKeyValue: id,
      item: data
    } 
  };

  const endpoint = "/data-api/graphql";
  const res = await fetch(endpoint, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(query)
  });

  const result = await res.json();
  console.table(result.data.updatePerson);
}

이 예에서는 다음이 적용됩니다.

  • GraphQL 쿼리는 데이터베이스에서 id 필드와 Name 필드를 선택합니다.
  • 개체는 query 속성에 GraphQL 쿼리를 저장합니다 query .
  • GraphQL 함수에 대한 인수 값은 속성을 통해 query.variables 전달됩니다.
  • 서버에 전달된 요청에는 속성에 쿼리 정의가 query 있는 페이로드가 필요합니다.
  • 응답 페이로드의 데이터는 속성에 data.updatePerson 있습니다.

페이지를 새로 고치고 업데이트 단추를 선택합니다.

이제 브라우저의 콘솔 창에 업데이트된 데이터를 보여 주는 테이블이 표시됩니다.

id 속성
1 몰리

만들기

index.html 태그 사이에 script 다음 코드를 추가합니다.

async function create() {

  const data = {
    id: "3",
    Name: "Pedro"
  };

  const gql = `
    mutation create($item: CreatePersonInput!) {
      createPerson(item: $item) {
        id
        Name
      }
    }`;
  
  const query = {
    query: gql,
    variables: {
      item: data
    } 
  };
  
  const endpoint = "/data-api/graphql";
  const result = await fetch(endpoint, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(query)
  });

  const response = await result.json();
  console.table(response.data.createPerson);
}

이 예에서는 다음이 적용됩니다.

  • GraphQL 쿼리는 데이터베이스에서 id 필드와 Name 필드를 선택합니다.
  • 개체는 query 속성에 GraphQL 쿼리를 저장합니다 query .
  • GraphQL 함수에 대한 인수 값은 속성을 통해 query.variables 전달됩니다.
  • 서버에 전달된 요청에는 속성에 쿼리 정의가 query 있는 페이로드가 필요합니다.
  • 응답 페이로드의 데이터는 속성에 data.updatePerson 있습니다.

페이지를 새로 고치고 만들기 단추를 선택합니다.

이제 브라우저의 콘솔 창에 데이터베이스의 새 레코드를 보여 주는 테이블이 표시됩니다.

id 이름
3 페드로

삭제

index.html 태그 사이에 script 다음 코드를 추가합니다.

async function del() {

  const id = '3';

  const gql = `
    mutation del($id: ID!, $_partitionKeyValue: String!) {
      deletePerson(id: $id, _partitionKeyValue: $_partitionKeyValue) {
        id
      }
    }`;

  const query = {
    query: gql,
    variables: {
      id: id,
    _partitionKeyValue: id
    }
  };

  const endpoint = "/data-api/graphql";
  const response = await fetch(endpoint, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(query)
  });

  const result = await response.json();
  console.log(`Record deleted: ${ JSON.stringify(result.data) }`);
}

이 예에서는 다음이 적용됩니다.

  • GraphQL 쿼리는 Id 데이터베이스에서 필드를 선택합니다.
  • 개체는 query 속성에 GraphQL 쿼리를 저장합니다 query .
  • GraphQL 함수에 대한 인수 값은 속성을 통해 query.variables 전달됩니다.
  • 서버에 전달된 요청에는 속성에 쿼리 정의가 query 있는 페이로드가 필요합니다.
  • 응답 페이로드의 데이터는 속성에 data.deletePerson 있습니다.

페이지를 새로 고치고 삭제 단추를 선택합니다.

이제 브라우저의 콘솔 창에 삭제 요청의 응답을 보여 주는 테이블이 표시됩니다.

삭제된 레코드: 2

이제 사이트를 로컬로 작업했으므로 이제 Azure에 배포할 수 있습니다.

사이트 배포

이 사이트를 프로덕션 환경에 배포하려면 구성 파일을 커밋하고 변경 내용을 서버에 푸시하기만 하면 됩니다.

  1. 구성 변경 내용을 커밋합니다.

    git commit -am "Add database configuration"
    
  2. 변경 내용을 서버에 푸시합니다.

    git push origin main
    
  3. 웹앱이 빌드되기를 기다립니다.

  4. 브라우저에서 정적 웹앱으로 이동합니다.

  5. 목록 단추를 선택하여 모든 항목을 나열합니다.

    출력은 이 스크린샷에 표시된 것과 유사해야 합니다.

    Web browser showing results from listing records from the database in the developer tools console window.

정적 웹앱에 데이터베이스 커넥트

다음 단계를 사용하여 사이트의 Static Web Apps 인스턴스와 데이터베이스 간에 연결을 만듭니다.

  1. Azure Portal에서 정적 웹앱을 엽니다.

  2. 설정 섹션에서 데이터베이스 연결을 선택합니다.

  3. 프로덕션 섹션에서 기존 데이터베이스 링크 링크를 선택합니다.

  4. 기존 데이터베이스 연결 창에서 다음 값을 입력합니다.

    속성
    데이터베이스 유형 드롭다운 목록에서 데이터베이스 유형을 선택합니다.
    구독 드롭다운 목록에서 Azure 구독을 선택합니다.
    데이터베이스 이름 정적 웹앱에 연결하려는 데이터베이스의 이름을 선택합니다.
    인증 유형 커넥트ion 문자열을 선택합니다.
  5. 확인을 선택합니다.

데이터베이스가 Static Web Apps 리소스에 연결되어 있는지 확인

데이터베이스를 정적 웹앱에 연결하고 사이트 빌드가 완료되면 다음 단계를 사용하여 데이터베이스 연결을 확인합니다.

  1. Azure Portal에서 정적 웹앱을 엽니다.

  2. Essentials 섹션에서 Static Web Apps 리소스의 URL을 선택하여 정적 웹앱으로 이동합니다.

  3. 목록 단추를 선택하여 모든 항목을 나열합니다.

    출력은 이 스크린샷에 표시된 것과 유사해야 합니다.

    Web browser showing results from listing records from the database in the developer tools console window.

리소스 정리

이 자습서에서 만든 리소스를 제거하려면 데이터베이스 연결을 해제하고 샘플 데이터를 제거해야 합니다.

  1. 데이터베이스 연결 해제: Azure Portal에서 정적 웹앱을 엽니다. 설정 섹션에서 데이터베이스 연결을 선택합니다. 연결된 데이터베이스 옆에 있는 세부 정보 보기를 선택합니다. 데이터베이스 연결 세부 정보 창에서 연결 해제 단추를 선택합니다.

  2. 샘플 데이터 제거: 데이터베이스에서 이름이 지정된 MyTestPersonContainer테이블을 삭제합니다.

다음 단계