Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to consume GraphQL Subscription with Flutter?

I am creating a subscription with GraphQL, and I need to consume that subscription with Flutter, but I don't know how to do that, the thing that I need is something like a UI component that would be tied to a subscription and it will be automatically refreshed.

I will appreciate any feedback.

like image 883
Joseph Arriaza Avatar asked Sep 25 '18 13:09

Joseph Arriaza


People also ask

How do you consume GraphQL API in Flutter?

In the main. dart file, change the MyApp widget from a StatelessWidget to a StatefulWidget . To connect our Flutter app to the GraphQL server, we need to create a GraphQLClient , which requires a Link and a GraphQLCache . The instance of GraphQLClient is passed to a ValueNotifier .

How do you integrate a GraphQL with Flutter?

You just need to make an HTTP request from the Flutter app, then use the returned data to set up the UI and display them. The new graphql_flutter plugin provides APIs and widgets that enable you to fetch and use data from a GraphQL backend with ease.

Is GraphQL subscription Websocket?

What are GraphQL Subscriptions? Subscriptions are a GraphQL feature allowing the server to send data to its clients when a specific event happens. Subscriptions are usually implemented with WebSockets, where the server holds a steady connection to the client.

How does GraphQL subscription work?

GraphQL subscriptions are made majorly to listen to when data is created on the server, when a data is updated, when a data is deleted, and when a data is read via query. The event to emitted is dependent on what the dev wants. The events are pushed from the server to the subscribing clients.


2 Answers

My GraphqlServer runs a subscription named getLogs which returns the log information in the following format.

{
  "data": {
    "getLogs": {
      "timeStamp": "18:09:24",
      "logLevel": "DEBUG",
      "file": "logger.py",
      "function": "init",
      "line": "1",
      "message": "Hello from logger.py"
    }
  }
}

If you are like me who wants to use only the GraphQL Client directly, then following sample could help.

import 'package:graphql/client.dart';
import 'package:graphql/internal.dart';
import 'package:flutter/material.dart';
import 'dart:async';

class LogPuller extends StatefulWidget {
  static final WebSocketLink _webSocketLink = WebSocketLink(
    url: 'ws://localhost:8000/graphql/',
    config: SocketClientConfig(
      autoReconnect: true,
    ),
  );

  static final Link _link = _webSocketLink;

  @override
  _LogPullerState createState() => _LogPullerState();
}

class _LogPullerState extends State<LogPuller> {
  final GraphQLClient _client = GraphQLClient(
    link: LogPuller._link,
    cache: InMemoryCache(),
  );

  // the subscription query should be of the following format. Note how the 'GetMyLogs' is used as the operation name below.
  final String subscribeQuery = '''
    subscription GetMyLogs{
      getLogs{
        timeStamp
        logLevel
        file
        function
        line
        message
      }
    }
    ''';
  Operation operation;

  Stream<FetchResult> _logStream;

  @override
  void initState() {
    super.initState();
    // note operation name is important. If not provided the stream subscription fails after first pull.
    operation = Operation(document: subscribeQuery, operationName: 'GetMyLogs');
    _logStream = _client.subscribe(operation);
  }

  @override
  Widget build(BuildContext context) {
    return StreamBuilder(
      stream: _logStream,
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          return Center(
            child: Container(
              child: CircularProgressIndicator(
                strokeWidth: 1.0,
              ),
            ),
          );
        }
        if (snapshot.hasData) {
          return Center(
            child: Text(
              snapshot.data.data['getLogs']
                  ['message'], // This will change according to you needs.
            ),
          );
        }
        return Container();
      },
    );
  }
}

As I am using a StreamBuilder to build the widget it will take care of closing the stream. If this is not the case for you, stream.listen() method will return a StreamSubscription<FetchResult> object which you can call the cancel() method which can be done inside dispose() method of a stateful widget or any such method for a standalone Dart client.

like image 192
Abhilash Chandran Avatar answered Oct 28 '22 13:10

Abhilash Chandran


You can check the next library https://github.com/zino-app/graphql-flutter

like image 24
yussenn Avatar answered Oct 28 '22 12:10

yussenn