---
title: Flutter에서 GraphQL로 소프트웨어 데이터 관계 저장
slug: docs-kr/flutter/graphql/store-relational-data-using-graphql
description: GraphQL과 Flutter를 사용하여 관계형 데이터 저장 및 쿼리를 관리하는 방법. Back4App을 활용한 포인터, GeoPointer, 날짜-시간 데이터 유형의 생성 및 업데이트.
image: https://www.back4app.com/images/logo-social.png
createdAt: 2024-03-18T19:44:31.722Z
---

# GraphQL을 사용하여 관계형 데이터 저장하기



## 소개

지난 두 개의 튜토리얼에서는 Flutter 앱 프로젝트에서 Back4App 데이터베이스에 대해 GraphQL 쿼리와 변형을 수행했습니다. 우리는 [GraphQL Flutter](https://pub.dev/packages/graphql_flutter/install)를 GraphQL 클라이언트로 사용하고 있습니다. 이는 매우 강력하고 널리 사용되는 프로젝트입니다. 이러한 튜토리얼에서는 클래스에 가장 일반적인 유형을 가진 매우 간단한 데이터 모델을 사용했습니다.

Back4App은 관계형 데이터를 생성, 저장 및 쿼리할 수 있는 유연한 플랫폼입니다. 이 튜토리얼에서는 Back4App 백엔드에서 관계형 데이터를 저장하고 쿼리할 때 관계 및 포인터를 사용하는 방법을 보여주면서 이 기능을 깊이 탐구할 것입니다. 또한 Back4App이 제공하는 다른 데이터 유형인 GeoPointer 및 Datetime도 탐색할 것입니다.

## 목표

이 기사 끝에서 여러분은 다음을 할 수 있게 될 것입니다:

- **관계형 데이터 생성/업데이트 및 삭제 (포인터 및 관계 사용)**
- **GeoPointers 생성/업데이트**
- **날짜-시간 생성/업데이트.**

## 전제 조건

:::hint{type="info"}
**이 튜토리얼을 완료하려면 다음이 필요합니다:**

- 이전 두 가이드를 읽었는지 확인하세요 - [템플릿에서 시작하기](https://www.back4app.com/docs/flutter/graphql/flutter-graphql-project-with-source-code-download) 및 [GraphQL 변형](https://www.back4app.com/docs/flutter/graphql/flutter-crud-app-example).
- 프로젝트 파일을 [GitHub 저장소](https://github.com/templates-back4app/Flutter-GraphQL/tree/complex-mutations)에서 다운로드하세요. 이 파일에는 이전 코드와 필요한 새로운 GUI가 포함되어 있습니다.
- VS Code 또는 Android Studio와 같은 Flutter IDE에서 다운로드한 프로젝트를 엽니다.
- 여기에서 생성할 수 있는 Back4App 계정이 필요합니다.[여기](https://www.back4app.com/).&#x20;
- 이전 튜토리얼에 따라 튜토리얼을 Back4App에 연결하세요. [템플릿에서 시작하기](https://www.back4app.com/docs/flutter/graphql/flutter-graphql-project-with-source-code-download).
:::

## 1 - 백엔드 설정

우리의 [이전 프로젝트](https://www.back4app.com/docs/flutter/flutter-crud-app-example)에서 우리의 데이터 모델은 단일 클래스인 Language로 매우 간단했습니다. 이제 우리는 Language와 관련된 2개의 새로운 클래스를 추가하여 더 복잡하게 만들 것입니다.

**형식이 있는 창립자**

| **열 이름** | **설명**     |
| -------- | ---------- |
| 이름       | 언어의 창립자 이름 |

| **열 이름** | **설명**         |
| -------- | -------------- |
| 이름       | 소유 회사 이름       |
| 소유 날짜    | 회사가 소유권을 얻은 날짜 |
| 본사       | 회사의 본사 위치      |

우리는 클래스 **Language**와 클래스 **Founder** 간의 일대일 관계를 Parse Pointers를 사용하여 생성할 것입니다. 이는 특정 언어의 창립자를 알려줍니다. 그런 다음, 우리는 클래스 **Language**와 클래스 **Ownership** 간의 일대다 관계를 Parse Relations를 사용하여 생성할 것입니다. 이는 어떤 조직/회사가 언어를 소유하고 있는지, 그들의 본사 및 언어 소유권을 취득한 날짜를 알려줍니다. 데이터 모델은 다음과 같이 보일 것입니다:

![](https://api.archbee.com/api/optimize/yD3zCY-NNBBIfd0uqcfR5/MSTrpoeUG0ptgqYO82xGh_image.png)

우리 앱으로 이동하기 전에 필요한 클래스와 데이터를 백엔드에 생성합시다. Back4App 앱으로 가서 GraphQL Playground로 이동합니다. 아래의 뮤테이션을 사용하여 클래스 **Founder**를 생성하여 언어의 창립자 이름을 저장할 것입니다.

```dart
1   mutation CreateClass {
2   	createClass(input:{
3       name: "Founder"
4       schemaFields: {
5         addStrings: [{name: "name"}]
6       }
7     }){
8       class{
9         schemaFields{
10          name
11          __typename
12        }
13      }
14    }
15  }
```

이제 창립자의 이름으로 클래스를 채워봅시다. 다음 단계에서는 이 데이터를 사용하여 창립자 클래스에 포인팅하는 새로운 언어를 생성할 것입니다. 아래의 변이를 Back4App GraphQL Playground에서 사용하여 창립자를 생성하세요.

```dart
1   mutation CreateObject{
2     createFounder(input: {fields: {name: "James Gosling"}}){
3       founder{
4         id
5         name
6       }
7     }
8   }
```

여기에서 우리는 JAVA 프로그래밍 언어 창립자의 이름을 입력했습니다. 다른 사람들에 대해서도 비슷하게 할 수 있지만 지금은 이것으로 가이드를 충분히 진행할 수 있습니다.

이제 **Ownership** 클래스를 생성하여 언어 소유권, 설립 날짜(날짜-시간) 및 소유자의 본사 위치(GeoPointer)를 저장할 것입니다. 나중에 언어 클래스와 소유권 간의 관계를 생성할 것입니다. 아래 코드를 실행하여 클래스를 생성하세요:

```dart
1   mutation CreateClass {
2   	createClass(input:{
3       name: "Ownership"
4       schemaFields: {
5         addStrings: [{name: "name"}]
6         addDates: [{name: "date_owned"}]
7       }
8     }){
9       class{
10        schemaFields{
11          name
12          __typename
13        }
14      }
15    }
16  }  
```

이제 다음 변형을 사용하여 **Ownership&#x20;**&#xD074;래스를 채우십시오:

```dart
1   mutation CreateObject{
2     createOwnership(input: {fields: {name: "Sun Microsystems"}}){
3       ownership{
4         id
5         name
6       }
7     }
8   }
```

```dart
1   mutation CreateObject{
2     createOwnership(input: {fields: {name: "Oracle"}}){
3       ownership{
4         id
5         name
6       }
7     }
8   }
```

이제 페이지를 새로 고치고, <font color="#2166ae">`Ownership`</font> 클래스로 데이터베이스 브라우저로 이동하십시오. 오른쪽 상단에서 **새 열 추가**를 선택하십시오. 첫 번째 드롭다운에서 GeoPoint를 선택하고 두 번째 텍스트 필드에 **headquarters**라고 이름을 지정하십시오. 그리고 모든 것을 그대로 두고 **열 추가** 버튼을 누르십시오.

::Image[]{src="https://api.archbee.com/api/optimize/yD3zCY-NNBBIfd0uqcfR5/Agqec5Oovt3OYFjV0n0Fe_image.png" size="50" width="538" height="477" position="center" showCaption="false"}

그런 다음 데이터베이스 브라우저에서 <font color="#2166ae">`언어`</font> 수업으로 가십시오. 관계를 추가해 보겠습니다 <font color="#2166ae">`소유권`</font> 및 <font color="#2166ae">`창립자`</font> 클래스에. **새 열 추가**를 클릭한 다음 데이터 유형 포인터와 대상 클래스 선택: <font color="#2166ae">`창립자`</font>. 열에 동일한 이름 - 창립자 - 을 부여한 후 열 추가를 누르십시오.

::Image[]{src="https://api.archbee.com/api/optimize/yD3zCY-NNBBIfd0uqcfR5/O1dj3LFxgci_OtxB898BI_image.png" size="60" width="536" height="555" position="center" showCaption="false"}

이제 소유권이라는 새 열을 추가하여 관계 데이터 유형을 사용하고 클래스 <font color="#2166ae">`소유권`</font>을 선택하여 이 과정을 반복하십시오.

::Image[]{src="https://api.archbee.com/api/optimize/yD3zCY-NNBBIfd0uqcfR5/ALxoJ61kaL4mYrOdQMI6s_image.png" size="70" width="536" height="393" position="center" showCaption="false"}

이제 Flutter 앱에서 사용할 데이터 모델이 준비되었으며 데이터를 저장하고 업데이트할 수 있습니다.

## 2 - 포인터 생성/추가 및 삭제

이제 프로젝트 보일러플레이트 코드를 [GitHub 리포지토리](https://github.com/templates-back4app/Flutter-GraphQL/tree/complex-mutations)에서 다운로드하여 IDE에서 엽니다. Back4App에 프로젝트를 연결하려면 GraphQL Playground로 이동하여 아래 이미지에 표시된 대로 키와 API URL을 복사합니다. 이제 이를 <font color="#2166ae">`constants.dart`</font>에 붙여넣고 프로젝트를 실행합니다.

![](https://api.archbee.com/api/optimize/yD3zCY-NNBBIfd0uqcfR5/OO8tAOtsr-U2s62pAqSyy_image.png)

에뮬레이터에서 애플리케이션을 실행합니다. 하단의 **M** 플로팅 버튼으로 이동합니다. 그러면 간단한 변형을 수행했던 페이지로 이동합니다. 여기에서 추가 플로팅 액션 버튼 **CM**, 복잡한 GraphQL 변형을 수행하는 데 사용할 버튼입니다. **CM** 버튼을 클릭하면 이 가이드에서 수행할 각 작업에 대한 네 개의 버튼이 표시됩니다.

이제 <font color="#2166ae">`databaseutils.dart`</font> 파일을 열고 <font color="#2166ae">`addPointers()`</font> 메서드로 스크롤합니다. 여기에서 포인터 추가 로직을 추가할 것입니다. 우리는 James Gosling을 Java 언어의 창립자로 지정할 것입니다. 따라서 먼저 Back4App 백엔드로 이동하여 창립자(James Gosling)와 언어(Java)의 <font color="#2166ae">`objectId`</font>를 복사해야 합니다.

**데이터에 대한 포인터 업데이트/생성**

우리 앱으로 진행하십시오 <font color="#2166ae">`databaseutils.dart`</font> 및 <font color="#2166ae">`addPointers()`</font> 메서드에서 <font color="#2166ae">`String addPointerQuery`</font>를 초기화하여 Pointers를 추가하기 위한 GraphQL 쿼리를 다음과 같이 할당합니다:

```dart
1   String addPointerQuery=
2      '''
3       mutation addPointer(\$languageId: ID!, \$founderId: UpdateLanguageFieldsInput! ){
4         updateLanguage(input : {id : \$languageId, fields : \$founderId})
5         {
6           language{
7             objectId
8           }
9         }
10      }
11     ''';
```

그리고 <font color="#2166ae">`final 변수`</font>를 초기화하여 변수를 할당합니다. <font color="#2166ae">`rowObjectId`</font>와 <font color="#2166ae">`pointersId`</font>를 매개변수로 사용합니다.

- <font color="#2166ae">`rowObjectId`</font>- 우리가 가리킬 행의 객체 ID
- <font color="#2166ae">`pointersId`</font>- 가리킬 행의 객체 ID.

따라서 <font color="#2166ae">`변수`</font>를 다음과 같이 선언합니다:

```dart
1   final variable={
2     "userId" : rowObjectId,
3        "founderId": {
4          "founder": {
5            "link": pointersId
6          }
7        }
8      };
```

이제 마지막 가이드처럼 <font color="#2166ae">`GraphQLClient`</font>를 초기화하고 <font color="#2166ae">`QueryOptions()`</font>의 도움으로 쿼리를 전송하고 <font color="#2166ae">`QueryResults()`</font>의 인스턴스를 반환합니다.

```dart
1   GraphQlConfiguration configuration = GraphQlConfiguration();
2      GraphQLClient client = configuration.clientToQuery();
3
4      QueryResult queryResult = await client.query(
5        QueryOptions(documentNode: gql(addPointerQuery), variables: variable),
6      );
7       return queryResult;
```

당신의 <font color="#2166ae">`addPointers()`</font> 메서드는 다음과 같아야 합니다:

```dart
1   Future<QueryResult> addPointers(String rowObjectId, String pointersId) async{
2      print('addPointers');
3      //code for add/update Pointers
4      String addPointerQuery=
5      '''
6       mutation addPointer(\$languageId: ID!, \$founderId: UpdateLanguageFieldsInput! ){
7         updateLanguage(input : {id : \$languageId, fields : \$founderId})
8         {
9           language{
10            objectId
11          }
12       }
13     }
14     ''';
15     final variable={
16       "userId" : rowObjectId,
17       "founderId": {
18         "founder": {
19           "link": pointersId
20         }
21       }
22     };
23     GraphQlConfiguration configuration = GraphQlConfiguration();
24     GraphQLClient client = configuration.clientToQuery();
25
26     QueryResult queryResult = await client.query(
27       QueryOptions(documentNode: gql(addPointerQuery), variables: variable),
28     );
29      return queryResult;
30   }
```

이제 앱을 핫 리스타트하고, **CM** 버튼을 클릭한 후 **Add Pointers** 버튼을 누르세요. 여기서 첫 번째 텍스트 필드에 포인터를 추가해야 하는 <font color="#2166ae">`objectId`</font>를 입력하고, 두 번째 텍스트 필드에 포인터가 가리킬 <font color="#2166ae">`objectId`</font>를 입력한 후 **Done**. 이제 대시보드를 확인하면 **founder** 열 아래에 관계를 볼 수 있어야 합니다. 클릭하면 **Founder** 클래스가 가리키는 행으로 이동합니다.

**데이터에 대한 포인터 삭제**

이제 관계를 삭제하는 로직을 작성할 <font color="#2166ae">`deletePointers()`</font> 메서드로 진행합니다. 관계를 삭제하려면 위의 쿼리에 약간의 변경만 하면 됩니다. 즉, 변수에서 <font color="#2166ae">`"link"`</font>를 <font color="#2166ae">`"remove"`</font>로 변경하면 됩니다. 따라서 <font color="#2166ae">`final variable`</font>을 초기화한 후에는 다음과 같을 것입니다:

```dart
1   final variable={
2        "languageId" : rowObjectId,
3        "founderId": {
4          "founder": {
5            "remove": pointersId
6          }
7        }
8      };
```

나머지는 <font color="#2166ae">`addPointers()`</font>와 정확히 동일하게 보일 것입니다. 따라서 당신의 <font color="#2166ae">`deletePointers()`</font> 메서드는 다음과 같습니다:

```dart
1   Future<QueryResult> deletePointers(String rowObjectId, String pointersId) async{
2      print('deletePointers');
3      //code for delete pointers
4      String removePointersQuery=
5      '''
6       mutation addPointer(\$languageId: ID!, \$founderId: UpdateLanguageFieldsInput! ){
7         updateLanguage(input : {id : \$languageId, fields : \$founderId})
8         {
9           language{
10            objectId
11          }
12        }
13      }
14     ''';
15     final variable={
16       "languageId" : rowObjectId,
17       "founderId": {
18         "founder": {
19           "remove": pointersId
20         }
21       }
22     };
23     GraphQlConfiguration configuration = GraphQlConfiguration();
24     GraphQLClient client = configuration.clientToQuery();
25  
26     QueryResult queryResult = await client.query(
27       QueryOptions(documentNode: gql(removePointersQuery), variables: variable),
28     );
29     return queryResult;
30
31   }
```

이제 Back4App 대시보드로 이동하여 특정 행의 \*창립자 열이 삭제된 것을 확인할 수 있습니다.

## 3 - 날짜-시간 데이터 생성/추가 및 삭제

기억하신다면 우리는 **Ownership** 클래스를 *Step 1*에서 생성하고 그 안에 데이터를 저장했습니다. 이들은 Java 프로그래밍 언어를 소유한 회사들의 이름입니다. 그러므로 먼저 소유권을 취득한 날짜를 입력해 보겠습니다.

이제 <font color="#2166ae">`databaseutils.dart`</font>로 이동하여 <font color="#2166ae">`addDateTime()`</font> 함수를 생성하거나 스크롤하여 찾습니다. 여기서 우리는 클래스에 날짜-시간 데이터 유형을 추가하는 로직을 작성할 것입니다. <font color="#2166ae">`String addDateTimeQuery`</font>를 초기화하고 날짜-시간 데이터를 생성하기 위한 쿼리를 할당합니다:

```dart
1   String addDateTimeQuery=
2      '''
3      mutation addTime(\$rowId: ID!,\$dateOwned: Date!){
4         updateOwnership(input : {id : \$rowId, fields : {date_owned : \$dateOwned}})
5         {
6           ownership{
7             objectId
8           }
9         }
10      } 
11     ''';
```

그리고 <font color="#2166ae">`final 변수`</font>는 다음과 같습니다:

```dart
1   final variable={
2        "rowId": rowObjectId,
3        "dateOwned": dateTime
4      };
```

이제 <font color="#2166ae">`GraphQLClient`</font>를 초기화하고 <font color="#2166ae">`QueryOption()`</font>을 통해 쿼리를 전달하세요. 이것이 당신의 함수가 어떻게 보일지입니다:

```dart
1   Future<QueryResult> addDateTime(String rowObjectId, String dateTime) async{
2      print('addDateTime');
3      //code for add/update date-time
4      String addDateTimeQuery=
5       '''
6       mutation addTime(\$rowId: ID!,\$dateOwned: Date!){
7         updateOwnership(input : {id : \$rowId, fields : {date_owned : \$dateOwned}})
8         {
9           ownership{
10            objectId
11          }
12        }
13      } 
14     ''';
15     final variable={
16       "rowId": rowObjectId,
17       "dateOwned": dateTime
18     };
19     GraphQlConfiguration configuration = GraphQlConfiguration();
20     GraphQLClient client = configuration.clientToQuery();
21     QueryResult queryResult = await client.query(
22       QueryOptions(documentNode: gql(addDateTimeQuery), variables: variable),
23     );
24     return queryResult;
25   }
```

이제 **Hot Restart** 애플리케이션을 실행하고 **objectId**를 기록하세요. *Sun Microsystems*이 포함된 행의 **name** 열에서. **Add Date-time** 버튼을 누르세요. 이제 첫 번째 텍스트 필드에 기록한 *objectId*를 입력하고 **“02-24-1982”**&#xB97C; **MM-DD-YYYY** 형식으로 입력한 후 Java가 발표된 날에 **Done** 버튼을 누르세요.

Back4App 백엔드로 진행하면 **24 Feb 1982 at 00:00:00 UTC** 형식으로 날짜가 표시되며, 이는 데이터 유형이 날짜-시간 데이터 유형으로 식별되었음을 의미합니다. 마찬가지로 **“01-27-2010”**&#xC744; **date\_owned**에 추가할 수 있습니다.*Oracle*에 대해.

## 4 - GeoPointer 데이터 추가/업데이트

회사의 본사를 찾기 위해 **Ownership** 테이블에 GeoPointer 데이터를 추가해 보겠습니다.
&#x20;`database_utils.dart` 파일로 이동하여 아래로 스크롤하여 `addGeoPointers()` 함수로 가십시오. 이제 `String addGeoPointers`를 초기화하고 해당 쿼리를 할당합니다:

```dart
1   String addGeoPointers=
2       '''
3       mutation addGeoPointer(\$objectId: ID!,\$latitude: Float!,\$longitude: Float!){
4         updateOwnership(input : {id : \$objectId, fields : { headquarters:  {latitude : \$latitude, longitude : \$longitude}}})
5         {
6           ownership{
7             objectId
8           }
9         }
10      } 
11      ''';
```

그리고 `final variable`로:

```dart
1   final variable={
2        "objectId": rowObjectId,
3        "latitude": double.parse(latitude),
4        "longitude":  double.parse(longitude),
5      };
```

위도 `latitude`와 `longitude`가 double 값이므로, 이를 String에서 double로 파싱해야 합니다. `GrapQLClient`를 초기화하고 `QueryOption()`로 쿼리를 전달합니다. 이렇게 하면 `addGeoPointers()` 함수는 다음과 같이 보일 것입니다:

```dart
1   Future<QueryResult> addGeoPointers(String rowObjectId, String latitude, String longitude) async{
2      print('add GeoPointers');
3      //code for add/update Geopointers
4      String addGeoPointers=
5       '''
6       mutation addGeoPointer(\$objectId: ID!,\$latitude: Float!,\$longitude: Float!){
7         updateOwnership(input : {id : \$objectId, fields : { headquarters:  {latitude : \$latitude, longitude : \$longitude}}})
8         {
9           ownership{
10            objectId
11          }
12        }
13      } 
14      ''';
15     final variable={
16       "objectId": rowObjectId,
17       "latitude": double.parse(latitude),
18       "longitude":  double.parse(longitude),
19     };
20     GraphQlConfiguration configuration = GraphQlConfiguration();
21     GraphQLClient client = configuration.clientToQuery();
22     QueryResult queryResult = await client.query(
23       QueryOptions(documentNode: gql(addGeoPointers), variables: variable),
24     );
25     return queryResult;
26   }
```

앱을 핫 리스타트하고 **Add GeoPointers** 버튼을 선택하세요. 첫 번째 텍스트 상자에 <font color="#2166ae">`37.35`</font>를 입력하고 두 번째 텍스트 상자에 <font color="#2166ae">`121.95`</font>를 입력하세요. Sun Microsystems의 **objectId**를 입력하고 **name**을 입력한 후 완료를 누르세요. 이제 Back4App 백엔드로 이동하면 **(37.35, 121.95)**&#xAC00; 표시되며, 이는 본사를 나타내는 좌표로 GeoPointers로 식별됩니다.

![](https://api.archbee.com/api/optimize/yD3zCY-NNBBIfd0uqcfR5/TN9iBvaF5x-BMN2ydq0DI_image.png)

## 5 - 관계 추가/업데이트 및 삭제

포인터는 한 행만 가리킬 수 있지만, 관계의 도움으로 여러 행에 연결할 수 있습니다. 따라서 **Language** 테이블을 **Ownership**의 **Java** 언어에 대해 이 두 행과 관계를 맺어 보겠습니다.

**관계 추가/업데이트**

다음으로 진행하십시오 <font color="#2166ae">`database_utils.dart`</font> 파일로 가서 <font color="#2166ae">`addRelation()`</font> 함수로 로직을 작성하십시오. <font color="#2166ae">`String addRelationQuery`</font>를 초기화하고 관계에 대한 쿼리를 다음과 같이 할당하십시오:

```dart
1   String addRelationQuery=
2        '''
3        mutation addRelation(\$objectId: ID!, \$relationId: OwnershipRelationInput){
4         updateLanguage(input : {id : \$objectId, fields : {ownership : \$relationId}})
5           {
6             language{
7               objectId
8             }
9           }
10         }
11       ''';
```

그리고 <font color="#2166ae">`최종 변수`</font>는 다음과 같습니다:

```dart
1   final variable= {
2        "objectId": objectId,
3        "relationId": relationId
4      };
```

따라서 <font color="#2166ae">`GraphQLClient`</font>를 초기화하고 이전과 같이 쿼리를 전달한 후, 당신의 <font color="#2166ae">`database_utils.dart`</font>는 다음과 같이 보일 것입니다:

```dart
1   Future<QueryResult> addRelation(String rowObjectId, String relationId) async{
2      //code for add/update Relation.
3      print('addRelation');
4      String addRelationQuery=
5        '''
6        mutation addRelation(\$objectId: ID!, \$relationId: OwnershipRelationInput){
7         updateLanguage(input : {id : \$objectId, fields : {ownership : \$relationId}})
8           {
9             language{
10              objectId
11            }
12          }
13        }
14       ''';
15     final variable= {
16       "objectId": rowObjectId,
17       "relationId": {
18         "add": relationId
19       }
20     };
21     GraphQlConfiguration configuration = GraphQlConfiguration();
22     GraphQLClient client = configuration.clientToQuery();
23     QueryResult queryResult = await client.query(
24       QueryOptions(documentNode: gql(addRelationQuery), variables: variable),
25     );
26     print(queryResult);
27     return queryResult;
28   }
```

***성공*** 귀하의 앱이 드디어 Back4App에 관계형, 날짜 및 GeoPointers 데이터를 저장했습니다!

## 결론

이 가이드에서는 Flutter 앱 프로젝트를 사용하여 Back4App에 관계형 데이터를 저장하는 방법을 배웠습니다. 또한 GeoPointers 및 Datetime과 같은 다른 GraphQL 변형을 사용하여 데이터를 생성, 업데이트 및 삭제하는 작업을 수행했습니다. 다음 튜토리얼에서는 Flutter 앱에 대한 쿼리를 깊이 있게 다룰 것입니다.

이 가이드는 [HybrowLabs](https://www.back4app.com/partners/software-development-company)에 의해 작성되었습니다.
