Dart SDK
The FraiseQL Dart SDK provides an async HTTP client for querying FraiseQL GraphQL APIs and schema annotations for defining types. It works in Dart CLI applications and Flutter mobile/web apps.
Installation
Section titled “Installation”dependencies: fraiseql: ^2.1.0dart pub getRequirements: Dart >= 3.0.0
Client
Section titled “Client”Creating a client
Section titled “Creating a client”import 'package:fraiseql/fraiseql.dart';
// Simple clientfinal client = FraiseQLClient.simple('http://localhost:8080/graphql');
// Full configurationfinal client = FraiseQLClient(FraiseQLClientConfig( url: 'http://localhost:8080/graphql', authorization: 'Bearer eyJhbGciOiJIUzI1NiIs...', timeout: Duration(seconds: 30),));Async authorization factory
Section titled “Async authorization factory”For JWT refresh or OAuth token rotation, pass an async factory instead of a static token:
final client = FraiseQLClient(FraiseQLClientConfig( url: 'http://localhost:8080/graphql', authorizationFactory: () async { final token = await refreshAccessToken(); return 'Bearer $token'; },));The factory is called on every request, so you can return a fresh token each time.
Queries
Section titled “Queries”final result = await client.query('{ users { id name email } }');print(result['data']['users']);
// With variablesfinal result = await client.query( r'query($id: ID!) { user(id: $id) { name } }', variables: {'id': 'user-123'}, operationName: 'GetUser',);Mutations
Section titled “Mutations”final result = await client.mutate( r'mutation($input: CreateUserInput!) { createUser(input: $input) { id } }', variables: { 'input': {'name': 'Alice', 'email': 'alice@example.com'}, },);Resource cleanup
Section titled “Resource cleanup”Always close the client when done to release HTTP connections:
await client.close();If you inject your own http.Client via FraiseQLClientConfig.httpClient, the SDK will not close it — you manage its lifecycle.
Error Handling
Section titled “Error Handling”All exceptions inherit from FraiseQLException:
| Exception | When thrown | Key properties |
|---|---|---|
GraphQLException | Response contains errors array | errors (full list), message (first error) |
NetworkException | Connection refused, DNS failure | message |
TimeoutException | Request exceeded timeout | duration |
AuthenticationException | HTTP 401 or 403 | statusCode |
RateLimitException | HTTP 429 | retryAfter |
try { final result = await client.query('{ users { id } }');} on AuthenticationException catch (e) { print('Auth failed (${e.statusCode})');} on RateLimitException { print('Rate limited — retry later');} on GraphQLException catch (e) { print('GraphQL error: ${e.message}'); for (final err in e.errors) { print(err['message']); }} on NetworkException catch (e) { print('Network error: ${e.message}');}Gemini Integration
Section titled “Gemini Integration”Wrap FraiseQL queries as Google Gemini tool definitions for use with the Generative AI API:
final descriptor = FraiseQLGeminiToolDescriptor( client: client, name: 'get_users', description: 'Fetch users by role', query: r'query($role: String!) { users(role: $role) { id name } }', parametersSchema: { 'type': 'object', 'properties': { 'role': {'type': 'string'}, }, 'required': ['role'], },);
// Execute the query with arguments from the modelfinal result = await descriptor.execute({'role': 'admin'});Works with both google_generative_ai and firebase_vertexai packages.
Schema Annotations
Section titled “Schema Annotations”Define GraphQL types using annotations:
@FraiseQLType(name: 'User', description: 'A registered user')class User { @FraiseQLField(name: 'id', required: true, description: 'Unique identifier') final String id;
@FraiseQLField(name: 'email', required: false) final String? email;
@FraiseQLField(name: 'legacyField', deprecated: true) final String? legacyField;
User({required this.id, this.email, this.legacyField});}These are metadata annotations for reflection. They do not generate schema output or validate against compiled schemas.
Transport Annotations
Section titled “Transport Annotations”gRPC endpoints are auto-generated when [grpc] is enabled — no per-operation annotation needed. See gRPC Transport.
Next Steps
Section titled “Next Steps”- SDK Overview — how compile-time authoring works
- SQL Patterns — view and function conventions
- All SDKs — compare languages