Flutter에서 GraphQL 사용하기
Flutter를 클라이언트에서 GraphQL을 사용하는 방법에 대한 글입니다.
'https://rickandmortyapi.com/graphql' GraphQL API를 이용해 Query를 호출하는 방법을 정리하도록 하겠습니다.
graphql_fultter
Flutter 프로젝트에서 GraphQL을 사용하기 위해서는 graphql_fultter를 사용해야 합니다.
21년 4월 7일 기준으로 최신 버전은 4.0.1 버전이므로, pubspec.yaml
의 dependencies
항목에 아래와 같이 패키지를 추가합니다.
dependencies:
graphql_flutter: ^4.0.1
그 후, flutter pub get
명령어를 실행해 flutter 프로젝트에 설치하면 적용이 완료됩니다.
import 'package:graphql_flutter/graphql_flutter.dart';
사용할 때는 위와 같이 import
하여 사용할 수 있습니다.
GraphQL config
인증이 필요하지 않은 서비스
class Config {
static final HttpLink _httpLink =
HttpLink('https://rickandmortyapi.com/graphql');
static ValueNotifier<GraphQLClient> initClient() {
ValueNotifier<GraphQLClient> client = ValueNotifier(
GraphQLClient(
link: _httpLink,
cache: GraphQLCache(),
),
);
return client;
}
}
인증이 필요하지 않는 서비스의 경우 위와 같이 작성해 initClient
메소드를 호출하여 GraphQL Client를 반환받을 수 있습니다.
사용할 API의 경우 인증이 필요하지 않으므로 위와 같이 HttpLink
를 생성 후, GraphQLClient
의 link
에 넘겨서 작성합니다.
인증이 필요한 서비스
import 'package:flutter/material.dart';
import 'package:graphql_flutter/graphql_flutter.dart';
class Config {
static final HttpLink _httpLink =
HttpLink('https://api.github.com/graphql');
static final AuthLink _authLink = AuthLink(
getToken: () async => 'Bearer <YOUR_PERSONAL_ACCESS_TOKEN>',
);
static final Link link = _authLink.concat(_httpLink);
static ValueNotifier<GraphQLClient> initClient() {
ValueNotifier<GraphQLClient> client = ValueNotifier(
GraphQLClient(
link: link,
cache: GraphQLCache(),
),
);
return client;
}
}
인증이 필요한 경우, 위와 같이 AuthLink
를 생성하여 HttpLink
를 concat
을 해주면 token 정보를 넘겨줄 수 있습니다.
GraphQL Provider 작성
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return GraphQLProvider(
client: Config.initClient(),
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
),
);
}
}
Query
와 Mutation
을 사용하기 위해서 GraphQLProvider
를 사용해 래핑해야 합니다.
main.dart
의 MyApp
위젯에서 GraphQLProvider
를 반환하도록 한 뒤, MaterialApp
위젯은 child
로 넘겨줍니다.
Query
Query 작성하기
query characters {
characters(page: 1) {
results {
id
name
}
}
}
위 Query
를 Flutter에서 사용할 수 있도록 Queries
클래스를 작성해줍니다.
class Queries {
static final String characters = """
query characters(\$page: Int!) {
characters(page: \$page) {
results {
id
name
}
}
}
""";
}
Queries
클래스에 static 메소드로 생성한 뒤, page
variables 값을 전달받을 수 있도록 위와 같이 작성합니다.
Query 사용하기
class CharacterList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Query(
options: QueryOptions(
document: gql(Queries.characters),
variables: {'page': 1},
),
builder: (result, {refetch, fetchMore}) {
if (result.hasException) return Text(result.exception.toString());
if (result.isLoading) return Text('Loading');
List characters = result.data['characters']['results'];
List<Widget> charactersWidgets = characters.map<Widget>((character) {
return Text('${character['id']}. ${character['name']}');
}).toList();
return ListView(
shrinkWrap: true,
children: charactersWidgets,
);
},
);
}
}
Query
를 사용하기 위해서는 Query
위젯을 사용해야 합니다.
QueryOptions
에 document
및 variables
을 작성한 다음, options
로 넘긴 후, builder
로 값을 받을 수 있도록 위와 같이 작성합니다.
Exception이 발생하거나 로딩 중일 경우, 각 상태에 맞는 텍스트를 보여주고 있습니다.
값이 정상적으로 들어왔다면 넘겨받은 값의 characters.results
값을 받은 후, map
을 이용해 List<Widget>
타입으로 변환해주고 사용해주면 됩니다.
위 사진은 List<Widget>
으로 변환한 값을 ListView
로 넘겨 출력하고 있는 모습입니다.