Skip to content

andrespd99/simple_graphql

Repository files navigation

SimpleGraphQL

style: very good analysis Powered by Mason License: BSD 3-Clause

Introduction

A simplified version of graphql package that saves you from all the boilerplate code. Cheers 🍻!

Get started

Like the name implies, using this package is simple. Just import it and create a new SimpleGraphQL instance with your custom URL.

import 'package:simple_graphql/simple_graphql.dart';

final client = SimpleGraphQL(apiUrl: 'https://api.example/graphql');

1st Note: API URLs must specify the /graphql or any other path at the end.

2nd Note: Setting the apiUrl property in the constructor is optional. More on this later.

Create a query

To execute a query, just call the query() method.

final client = SimpleGraphQL(apiUrl: 'https://api.example/graphql');

final result = client.query(
  query: "<Your query goes here>",
  resultBuilder: (data) {
    // Here is where you would want to serialize the result.
    return data;
  },
);

The resultBuilder parameter is a handy builder that returns a Map with the decoded result. Here's were you would normally serialize the result into a concrete object, or return the raw Map directly.

When serializing to concrete classes, it is recommended to specify the type of the class, like so:

final result = client.query<User>(
  query: '''
    query ExampleQuery() {
      getUser {
        id,
        name,
        email
      }
    }
  
  ''',
  resultBuilder: (data) {
    return User.fromMap(data['getUser']);
  },
);

The first layer of the Map parameter of resultBuilder will always be named like the query or mutation being called. In the example above, the query is named getUser.

Create a mutation

Similar to executing queries, to execute a mutation, call the mutation() method.

final client = SimpleGraphQL(apiUrl: 'https://api.example/graphql');

final result = client.mutation(
  query: "<Your mutation goes here>",
  resultBuilder: (data) {
    // Here is where you would want to serialize the result.
    return data;
  },
);

Advanced usage

Authentication with token-based requests

You can set a token to be used in the authorization header in two ways. You can either set it on the constructor, or on each query/mutation.

Set token on constructor

final client = SimpleGraphQL(
  apiUrl: 'https://api.example/graphql',
  token: 'Bearer $token', // Must include prefixes, like "Bearer"
  authHeaderKey = 'Authorization', // Optional, defaults to 'Authorization'
);

This will set the token to be used in the [AuthLink] on all queries and mutations.

Set token on query or mutation

final client = SimpleGraphQL(apiUrl: 'https://api.example/graphql');

final result = client.query(
  query: "<Your query goes here>",
  resultBuilder: (data) {
    // Here is where you would want to serialize the result.
    return data;
  },
  token: 'Bearer $token', // Must include prefixes, like "Bearer"
  authHeaderKey = 'Authorization', // Optional, defaults to 'Authorization'
);

This will set the token to be used in the [AuthLink] on the query or mutation. Will override any token set on the constructor.

Custom headers

You can set custom headers in different ways, similar to the token. You can either set them on the constructor, or on each query/mutation.

Set headers on constructor

final client = SimpleGraphQL(
  apiUrl: 'https://api.example/graphql',
  defaultHeaders: {
    'customHeaderKey': 'Custom value',
  },
);

Set headers on query or mutation

final client = SimpleGraphQL(apiUrl: 'https://api.example/graphql');

final result = client.query(
  headers: {
    'customHeaderKey': 'Custom value',
  },
  query: "<Your query goes here>",
  resultBuilder: (data) {
    // Here is where you would want to serialize the result.
    return data;
  },
);

By default, the headers parameter of both query() and mutation() methods will be merged with the defaultHeaders passed to the constructor. You can change this behavior with the headersInjectionBehavior parameter.

final client = SimpleGraphQL(
  apiUrl: 'https://api.myapi.example/graphql',
  headers: {
    'customHeaderKey': 'Custom value',
  },
);

final result = client.query(
  headers: {
    'newCustomHeaderKey': 'New custom value (overrides default)',
  },
  headersInjectionBehavior: HeadersInjectionBehavior.override,
  query: "<Your query goes here>",
  resultBuilder: (data) => data,
);

This will in turn send a map with newCustomHeaderKey only, overriding the default headers.

Custom policies

Like the original package, you can define the policies for your petition.

The available policies are to be defined are fetching, error and cache re-read policies. Todo do so, you can set the policies for both query() and mutation() methods via parameter, with the same [Policies] class from graphql package. Example below:

final client = SimpleGraphQL()

final result = client.mutation(
  fetchPolicy: FetchPolicy.noCache,
  cacheRereadPolicy: CacheRereadPolicy.mergeOptimistic,
  errorPolicy: ErrorPolicy.ignore,
  mutation: ...,
  resultBuilder: (data) => ...,
);