728x90

Flutter를 클라이언트에서 GraphQL을 사용하는 방법에 대한 글입니다.

'https://rickandmortyapi.com/graphql' GraphQL API를 이용해 Query를 호출하는 방법을 정리하도록 하겠습니다.

graphql_fultter

Flutter 프로젝트에서 GraphQL을 사용하기 위해서는 graphql_fultter를 사용해야 합니다.

21년 4월 7일 기준으로 최신 버전은 4.0.1 버전이므로, pubspec.yamldependencies 항목에 아래와 같이 패키지를 추가합니다.

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를 생성 후, GraphQLClientlink에 넘겨서 작성합니다.

인증이 필요한 서비스

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를 생성하여 HttpLinkconcat을 해주면 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'),
      ),
    );
  }
}

QueryMutation을 사용하기 위해서 GraphQLProvider를 사용해 래핑해야 합니다.

main.dartMyApp 위젯에서 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 위젯을 사용해야 합니다.

QueryOptionsdocumentvariables을 작성한 다음, options 로 넘긴 후, builder로 값을 받을 수 있도록 위와 같이 작성합니다.

Exception이 발생하거나 로딩 중일 경우, 각 상태에 맞는 텍스트를 보여주고 있습니다.

값이 정상적으로 들어왔다면 넘겨받은 값의 characters.results 값을 받은 후, map을 이용해 List<Widget> 타입으로 변환해주고 사용해주면 됩니다.

ListView로 출력한 모습

위 사진은 List<Widget>으로 변환한 값을 ListView로 넘겨 출력하고 있는 모습입니다.

728x90
728x90