request method

Future<GraphQLResponse> request(
  1. String document, {
  2. Map<String, dynamic>? variables,
  3. String? operationName,
  4. Map<String, dynamic>? extensions,
  5. CancelToken? cancelToken,
})

Executes document without discarding partial data or structured errors.

Implementation

Future<GraphQLResponse> request(
  String document, {
  Map<String, dynamic>? variables,
  String? operationName,
  Map<String, dynamic>? extensions,
  CancelToken? cancelToken,
}) async {
  late Response<dynamic> response;
  try {
    response = await _dio.post<dynamic>(
      endpoint,
      data: {
        'query': document,
        if (variables != null) 'variables': variables,
        if (operationName != null) 'operationName': operationName,
        if (extensions != null) 'extensions': extensions,
      },
      cancelToken: cancelToken,
      options: Options(
        contentType: Headers.jsonContentType,
        responseType: ResponseType.json,
        headers: {'accept': Headers.jsonContentType, ...headers},
        validateStatus: (_) => true,
      ),
    );
  } on DioException catch (error) {
    throw GraphQLRequestException(
      error.type == DioExceptionType.cancel
          ? 'GraphQL request cancelled'
          : 'GraphQL request failed${error.message == null ? '' : ': ${error.message}'}',
      statusCode: error.response?.statusCode,
      isCancelled: error.type == DioExceptionType.cancel,
    );
  }

  final statusCode = response.statusCode;
  if (statusCode == null || statusCode < 200 || statusCode >= 300) {
    throw GraphQLRequestException(
      'GraphQL request failed (HTTP ${statusCode ?? 'unknown'})',
      statusCode: statusCode,
    );
  }

  dynamic rawBody = response.data;
  if (rawBody is String) {
    try {
      rawBody = jsonDecode(rawBody);
    } on FormatException {
      throw const GraphQLRequestException('Invalid GraphQL JSON response');
    }
  }
  if (rawBody is! Map) {
    throw const GraphQLRequestException('Invalid GraphQL response body');
  }

  final body = Map<String, dynamic>.from(rawBody);
  final rawData = body['data'];
  final rawErrors = body['errors'];
  return GraphQLResponse(
    data: rawData is Map ? Map<String, dynamic>.from(rawData) : null,
    errors: rawErrors is List
        ? rawErrors
              .map(GraphQLError.fromJson)
              .whereType<GraphQLError>()
              .toList()
        : const [],
    extensions: body['extensions'] is Map
        ? Map<String, dynamic>.from(body['extensions'] as Map)
        : null,
  );
}