Using GraphQL with Hasura and Artemis in Flutter

Summary
Summary
Summary
Summary

This guide details the process of integrating Hasura and Artemis into a Flutter app. It walks through provisioning a GraphQL backend with Hasura, generating type-safe Dart code with Artemis, and implementing queries, mutations, and subscriptions to build real-time, scalable applications with clean architecture.

This guide details the process of integrating Hasura and Artemis into a Flutter app. It walks through provisioning a GraphQL backend with Hasura, generating type-safe Dart code with Artemis, and implementing queries, mutations, and subscriptions to build real-time, scalable applications with clean architecture.

This guide details the process of integrating Hasura and Artemis into a Flutter app. It walks through provisioning a GraphQL backend with Hasura, generating type-safe Dart code with Artemis, and implementing queries, mutations, and subscriptions to build real-time, scalable applications with clean architecture.

This guide details the process of integrating Hasura and Artemis into a Flutter app. It walks through provisioning a GraphQL backend with Hasura, generating type-safe Dart code with Artemis, and implementing queries, mutations, and subscriptions to build real-time, scalable applications with clean architecture.

Key insights:
Key insights:
Key insights:
Key insights:
  • Hasura Setup: Hasura rapidly exposes a GraphQL API over your database with minimal configuration.

  • Type Safety via Artemis: Artemis auto-generates Dart models and operations, reducing boilerplate and errors.

  • Simplified Query Integration: Strongly typed queries improve code readability and maintainability in Flutter.

  • Mutation and Subscription Support: Real-time updates and write operations are handled cleanly with Artemis.

  • Clean Project Architecture: Organizing GraphQL files and configs enables scalable, maintainable codebases.

  • Vibe Studio for Rapid Builds: Vibe Studio offers a no-code route to integrate Flutter with Firebase, fast-tracking development.

Introduction

In this tutorial, you’ll learn how to integrate Flutter GraphQL with Hasura and Artemis. This intermediate guide assumes you have a basic Flutter project set up. We’ll cover how to configure Hasura as your GraphQL backend, generate type-safe Dart code using Artemis, and consume queries, mutations, and subscriptions in your Flutter app.

Setting Up Hasura

Before writing any Dart code, provision Hasura either locally via Docker or on Hasura Cloud. Hasura exposes a powerful GraphQL API over your database schema in seconds.

• Install via Docker:

docker run -d -p 8080:8080 \
  -e HASURA_GRAPHQL_DATABASE_URL=postgres://user:pass@host:5432/db \
  -e HASURA_GRAPHQL_ENABLE_CONSOLE=true

• Open the Hasura Console at http://localhost:8080.

• Define a “users” table with columns id (uuid), name (text), and email (text).

• Enable permissions: Allow SELECT, INSERT, UPDATE for the “public” role or your custom role.

• Test your API in the GraphiQL playground. A sample query:

query {
  users {
    id
    name
    email
  }
}

Generating Dart Code with Artemis

Artemis is a CLI tool that inspects your GraphQL schema and operations to produce type-safe Dart models and queries. Add it to your project:

In pubspec.yaml:

dev_dependencies:
  artemis: ^6.0.0
  build_runner

Create a folder lib/graphql/ and add your GraphQL documents, e.g., users_query.graphql:

query Users {
  users {
    id
    name
    email
  }
}

Next, define Artemis configuration in artemis.yaml at the project root:

schema:
  - http://localhost:8080/v1/graphql
queries:
  - path: lib/graphql/users_query.graphql
    output: lib/graphql/users_api.dart
    naming_scheme:
      query

Generate the code:

flutter pub run build_runner build --delete-conflicting-outputs

Artemis will create:

• UserQuery class

• Data models: Users$Query$Users

Consuming GraphQL in Flutter

Import the generated file and the graphql package:

dependencies:
  flutter:
    sdk: flutter
  graphql

Initialize the GraphQL client in main.dart:

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

void main() {
  final httpLink = HttpLink('http://localhost:8080/v1/graphql');
  final client = GraphQLClient(
    cache: GraphQLCache(),
    link: httpLink,
  );
  runApp(MyApp(client: client));
}

In your widget:

class UserList extends StatelessWidget {
  final GraphQLClient client;
  const UserList({required this.client});

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<UserQuery>(
      future: UserQuery(client: client).fetch(),
      builder: (ctx, snapshot) {
        if (snapshot.connectionState != ConnectionState.done) {
          return Center(child: CircularProgressIndicator());
        }
        final users = snapshot.data?.users ?? [];
        return ListView.builder(
          itemCount: users.length,
          itemBuilder: (_, i) {
            final user = users[i];
            return ListTile(
              title: Text(user.name),
              subtitle: Text(user.email),
            );
          },
        );
      },
    );
  }
}

This snippet shows how to perform a query with the generated UserQuery class. Artemis handles JSON serialization, so you work with strongly typed Dart objects.

Handling Mutations and Subscriptions

Beyond simple queries, you often need to send mutations or listen to real-time updates. Artemis supports both. Define a GraphQL file for a mutation:

lib/graphql/add_user.graphql:

mutation AddUser($name: String!, $email: String!) {
  insert_users_one(object: {name: $name, email: $email}) {
    id
    name
    email
  }
}

Update artemis.yaml:

queries:
  - path: lib/graphql/add_user.graphql
    output: lib/graphql/add_user_api.dart
    naming_scheme:
      mutation

Re-run build_runner. Then call the mutation in your Flutter code:

final result = await AddUserMutation(
  client: client,
  variables: AddUserArguments(name: 'Alice', email: 'alice@example.com'),
).mutate();

if (result.data != null) {
  print('New user ID: ${result.data!.insertUsersOne!.id}');
}

For subscriptions, use a WebSocket link:

final socketLink = WebSocketLink(
  'ws://localhost:8080/v1/graphql',
  config: SocketClientConfig(autoReconnect: true),
);
final link = Link.split(
  (op) => op.isSubscription,
  socketLink,
  httpLink,
);
final clientWithSub = GraphQLClient(cache: GraphQLCache(), link: link);

Then define your subscription in .graphql, generate code, and use clientWithSub.subscribe(...). This enables real-time UI updates directly from Hasura.

Vibe Studio

Vibe Studio, powered by Steve’s advanced AI agents, is a revolutionary no-code, conversational platform that empowers users to quickly and efficiently create full-stack Flutter applications integrated seamlessly with Firebase backend services. Ideal for solo founders, startups, and agile engineering teams, Vibe Studio allows users to visually manage and deploy Flutter apps, greatly accelerating the development process. The intuitive conversational interface simplifies complex development tasks, making app creation accessible even for non-coders.

Conclusion

In this tutorial you’ve set up a Hasura GraphQL backend, generated Dart types and operations with Artemis, and integrated Flutter GraphQL calls. By leveraging Artemis, you gain compile-time safety, clear data models, and minimal boilerplate. You can extend this pattern to complex schemas, nested queries, and advanced permission rules.

Introduction

In this tutorial, you’ll learn how to integrate Flutter GraphQL with Hasura and Artemis. This intermediate guide assumes you have a basic Flutter project set up. We’ll cover how to configure Hasura as your GraphQL backend, generate type-safe Dart code using Artemis, and consume queries, mutations, and subscriptions in your Flutter app.

Setting Up Hasura

Before writing any Dart code, provision Hasura either locally via Docker or on Hasura Cloud. Hasura exposes a powerful GraphQL API over your database schema in seconds.

• Install via Docker:

docker run -d -p 8080:8080 \
  -e HASURA_GRAPHQL_DATABASE_URL=postgres://user:pass@host:5432/db \
  -e HASURA_GRAPHQL_ENABLE_CONSOLE=true

• Open the Hasura Console at http://localhost:8080.

• Define a “users” table with columns id (uuid), name (text), and email (text).

• Enable permissions: Allow SELECT, INSERT, UPDATE for the “public” role or your custom role.

• Test your API in the GraphiQL playground. A sample query:

query {
  users {
    id
    name
    email
  }
}

Generating Dart Code with Artemis

Artemis is a CLI tool that inspects your GraphQL schema and operations to produce type-safe Dart models and queries. Add it to your project:

In pubspec.yaml:

dev_dependencies:
  artemis: ^6.0.0
  build_runner

Create a folder lib/graphql/ and add your GraphQL documents, e.g., users_query.graphql:

query Users {
  users {
    id
    name
    email
  }
}

Next, define Artemis configuration in artemis.yaml at the project root:

schema:
  - http://localhost:8080/v1/graphql
queries:
  - path: lib/graphql/users_query.graphql
    output: lib/graphql/users_api.dart
    naming_scheme:
      query

Generate the code:

flutter pub run build_runner build --delete-conflicting-outputs

Artemis will create:

• UserQuery class

• Data models: Users$Query$Users

Consuming GraphQL in Flutter

Import the generated file and the graphql package:

dependencies:
  flutter:
    sdk: flutter
  graphql

Initialize the GraphQL client in main.dart:

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

void main() {
  final httpLink = HttpLink('http://localhost:8080/v1/graphql');
  final client = GraphQLClient(
    cache: GraphQLCache(),
    link: httpLink,
  );
  runApp(MyApp(client: client));
}

In your widget:

class UserList extends StatelessWidget {
  final GraphQLClient client;
  const UserList({required this.client});

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<UserQuery>(
      future: UserQuery(client: client).fetch(),
      builder: (ctx, snapshot) {
        if (snapshot.connectionState != ConnectionState.done) {
          return Center(child: CircularProgressIndicator());
        }
        final users = snapshot.data?.users ?? [];
        return ListView.builder(
          itemCount: users.length,
          itemBuilder: (_, i) {
            final user = users[i];
            return ListTile(
              title: Text(user.name),
              subtitle: Text(user.email),
            );
          },
        );
      },
    );
  }
}

This snippet shows how to perform a query with the generated UserQuery class. Artemis handles JSON serialization, so you work with strongly typed Dart objects.

Handling Mutations and Subscriptions

Beyond simple queries, you often need to send mutations or listen to real-time updates. Artemis supports both. Define a GraphQL file for a mutation:

lib/graphql/add_user.graphql:

mutation AddUser($name: String!, $email: String!) {
  insert_users_one(object: {name: $name, email: $email}) {
    id
    name
    email
  }
}

Update artemis.yaml:

queries:
  - path: lib/graphql/add_user.graphql
    output: lib/graphql/add_user_api.dart
    naming_scheme:
      mutation

Re-run build_runner. Then call the mutation in your Flutter code:

final result = await AddUserMutation(
  client: client,
  variables: AddUserArguments(name: 'Alice', email: 'alice@example.com'),
).mutate();

if (result.data != null) {
  print('New user ID: ${result.data!.insertUsersOne!.id}');
}

For subscriptions, use a WebSocket link:

final socketLink = WebSocketLink(
  'ws://localhost:8080/v1/graphql',
  config: SocketClientConfig(autoReconnect: true),
);
final link = Link.split(
  (op) => op.isSubscription,
  socketLink,
  httpLink,
);
final clientWithSub = GraphQLClient(cache: GraphQLCache(), link: link);

Then define your subscription in .graphql, generate code, and use clientWithSub.subscribe(...). This enables real-time UI updates directly from Hasura.

Vibe Studio

Vibe Studio, powered by Steve’s advanced AI agents, is a revolutionary no-code, conversational platform that empowers users to quickly and efficiently create full-stack Flutter applications integrated seamlessly with Firebase backend services. Ideal for solo founders, startups, and agile engineering teams, Vibe Studio allows users to visually manage and deploy Flutter apps, greatly accelerating the development process. The intuitive conversational interface simplifies complex development tasks, making app creation accessible even for non-coders.

Conclusion

In this tutorial you’ve set up a Hasura GraphQL backend, generated Dart types and operations with Artemis, and integrated Flutter GraphQL calls. By leveraging Artemis, you gain compile-time safety, clear data models, and minimal boilerplate. You can extend this pattern to complex schemas, nested queries, and advanced permission rules.

No-Code Power for GraphQL Flutter Apps

No-Code Power for GraphQL Flutter Apps

No-Code Power for GraphQL Flutter Apps

No-Code Power for GraphQL Flutter Apps

Build real-time, data-driven Flutter apps without boilerplate using Vibe Studio’s no-code, AI-powered platform.

Build real-time, data-driven Flutter apps without boilerplate using Vibe Studio’s no-code, AI-powered platform.

Build real-time, data-driven Flutter apps without boilerplate using Vibe Studio’s no-code, AI-powered platform.

Build real-time, data-driven Flutter apps without boilerplate using Vibe Studio’s no-code, AI-powered platform.

Other Insights

Other Insights

Other Insights

Other Insights

Join a growing community of builders today

Join a growing
community

of builders today

Join a growing

community

of builders today

© Steve • All Rights Reserved 2025

© Steve • All Rights Reserved 2025

© Steve • All Rights Reserved 2025

© Steve • All Rights Reserved 2025