Skip to main content

redis_dart_client 1.0.0 copy "redis_dart_client: ^1.0.0" to clipboard
redis_dart_client: ^1.0.0 copied to clipboard

A simple and lightweight Redis client for Dart.

Redis Dart Client #

Pub License: MIT Coverage GitHub stars

A simple and lightweight Redis client for Dart that provides basic Redis operations.

Features #

  • ✅ Simple and easy to use API
  • ✅ Support for common Redis commands (GET, SET, DELETE, EXISTS, etc.)
  • ✅ Connection management with authentication support
  • ✅ Type-safe operations
  • ✅ No external dependencies (uses Dart's built-in dart:io)
  • ✅ Optional response timeout
  • ✅ Simple pipeline batching
  • ✅ Full UTF-8 support (including Cyrillic, Chinese, emoji, and other Unicode characters)

Getting Started #

Installation #

Add this package to your pubspec.yaml:

dependencies:
  redis_dart_client: <version>

Then run:

dart pub get

Basic Usage #

import 'package:redis_dart_client/redis_dart_client.dart';

void main() async {
  // Create a Redis client
  final client = RedisClient(
    host: 'localhost',
    port: 6379,
    responseTimeout: const Duration(seconds: 2), // optional timeout
    // password: 'your_password', // Optional
  );

  try {
    // Connect to Redis
    await client.connect();

    // Set a key-value pair
    await client.set('name', 'Redis Client');

    // Get a value
    final value = await client.get('name');
    print(value); // Output: Redis Client

    // Check if key exists
    final exists = await client.exists('name');
    print(exists); // Output: true

    // Delete a key
    await client.delete(['name']);

    // Disconnect
    await client.disconnect();
  } catch (e) {
    print('Error: $e');
  }
}

Available Operations #

Connection Management #

  • connect() - Connects to the Redis server
  • disconnect() - Disconnects from the Redis server
  • isConnected - Checks if the client is connected

Basic Operations #

  • set(String key, String value) - Sets a key-value pair
  • get(String key) - Gets a value by key (returns null if key doesn't exist)
  • delete(List<String> keys) - Deletes one or more keys
  • exists(String key) - Checks if a key exists

Advanced Operations #

  • setex(String key, String value, int seconds) - Sets a key with expiration time
  • ttl(String key) - Gets the time to live of a key in seconds
  • incr(String key) - Increments the integer value of a key by 1
  • decr(String key) - Decrements the integer value of a key by 1
  • keys(String pattern) - Gets all keys matching a pattern (e.g., 'user:*')
  • pipeline(List<List<String>> commands) - Sends multiple commands without awaiting between them and then collects all responses

Examples #

Pipeline Example #

Pipeline allows you to send multiple commands efficiently without waiting for each response:

import 'package:redis_dart_client/redis_dart_client.dart';

void main() async {
  final client = RedisClient();
  await client.connect();

  try {
    // Execute multiple commands in a pipeline
    final results = await client.pipeline([
      ['SET', 'user:1', 'Alice'],
      ['SET', 'user:2', 'Bob'],
      ['GET', 'user:1'],
      ['GET', 'user:2'],
      ['INCR', 'visitor_count'],
      ['INCR', 'visitor_count'],
    ]);

    print('Results: $results');
    // Output: ['OK', 'OK', 'Alice', 'Bob', 1, 2]

    // Clean up
    await client.delete(['user:1', 'user:2', 'visitor_count']);
  } finally {
    await client.disconnect();
  }
}

Flutter Example #

This package works great with Flutter apps on mobile and desktop:

import 'package:flutter/material.dart';
import 'package:redis_dart_client/redis_dart_client.dart';

class RedisCacheService {
  late RedisClient _client;
  bool _isConnected = false;

  Future<void> initialize() async {
    _client = RedisClient(
      host: 'your-redis-server.com',
      port: 6379,
      password: 'your-password', // Optional
      responseTimeout: const Duration(seconds: 5),
    );

    try {
      await _client.connect();
      _isConnected = true;
    } on RedisException catch (e) {
      debugPrint('Failed to connect to Redis: $e');
      _isConnected = false;
    }
  }

  Future<String?> getCachedData(String key) async {
    if (!_isConnected) return null;
    
    try {
      return await _client.get(key);
    } on RedisException catch (e) {
      debugPrint('Error getting cache: $e');
      return null;
    }
  }

  Future<void> setCachedData(String key, String value, {int? ttl}) async {
    if (!_isConnected) return;
    
    try {
      if (ttl != null) {
        await _client.setex(key, value, ttl);
      } else {
        await _client.set(key, value);
      }
    } on RedisException catch (e) {
      debugPrint('Error setting cache: $e');
    }
  }

  Future<void> disconnect() async {
    if (_isConnected) {
      await _client.disconnect();
      _isConnected = false;
    }
  }
}

// Usage in a Flutter widget
class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final _cacheService = RedisCacheService();
  String? _cachedValue;

  @override
  void initState() {
    super.initState();
    _initializeCache();
  }

  Future<void> _initializeCache() async {
    await _cacheService.initialize();
    _cachedValue = await _cacheService.getCachedData('my_key');
    setState(() {});
  }

  @override
  void dispose() {
    _cacheService.disconnect();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Redis Cache Example')),
        body: Center(
          child: Text(_cachedValue ?? 'No cached value'),
        ),
      ),
    );
  }
}

See the example directory for a complete example demonstrating all available operations.

Running the Example #

To run the example, you need a Redis server running. The easiest way is to use Docker:

  1. Install Docker (if not already installed):

  2. Start a Redis container:

    docker run --rm -d -p 6379:6379 --name redis-test redis:alpine
    
  3. Run the example:

    cd example
    dart run lib/redis_dart_client_example.dart
    
  4. Stop the Redis container (when done):

    docker stop redis-test
    

The example demonstrates all available operations including SET, GET, DELETE, EXISTS, SETEX, TTL, INCR, DECR, KEYS, and pipeline operations.

Error Handling #

All operations can throw a RedisException if something goes wrong. Here are examples of proper error handling:

Basic Error Handling #

try {
  await client.set('key', 'value');
} on RedisException catch (e) {
  print('Redis error: $e');
}

Comprehensive Error Handling #

import 'package:redis_dart_client/redis_dart_client.dart';

void main() async {
  final client = RedisClient(
    host: 'localhost',
    port: 6379,
    responseTimeout: const Duration(seconds: 5),
  );

  try {
    await client.connect();
    
    // Perform operations
    await client.set('user:1', 'Alice');
    final value = await client.get('user:1');
    print('Value: $value');
    
  } on RedisException catch (e) {
    // Handle Redis-specific errors
    print('Redis operation failed: ${e.message}');
    
    // Check connection status
    if (!client.isConnected) {
      print('Connection lost. Attempting to reconnect...');
      try {
        await client.connect();
        print('Reconnected successfully');
      } catch (reconnectError) {
        print('Reconnection failed: $reconnectError');
      }
    }
  } catch (e) {
    // Handle other errors
    print('Unexpected error: $e');
  } finally {
    // Always disconnect
    if (client.isConnected) {
      await client.disconnect();
    }
  }
}

Requirements #

  • Dart SDK >= 3.1.0
  • Redis server running and accessible
  • (Optional) Docker to quickly start a local Redis instance

Supported Platforms #

This package uses dart:io for socket communication, which means it supports:

  • ✅ Dart (Server) - Command-line applications and server-side Dart
  • ✅ Flutter - Mobile and desktop applications
    • ✅ Android
    • ✅ iOS
    • ✅ Linux
    • ✅ macOS
    • ✅ Windows
  • ❌ Flutter Web - Not supported (browsers don't support dart:io)

Note: This package works perfectly with Flutter apps on mobile and desktop platforms. For Flutter web applications, consider using a Redis proxy or WebSocket-based solution.

Test Coverage #

The project has comprehensive test coverage with 44 tests covering all major functionality:

File Coverage
redis_client.dart >90% - All public methods and edge cases
redis_protocol.dart >75% - All RESP protocol types and error handling
redis_exception.dart ~100% - Full coverage of exception handling
Total >80% - Comprehensive test suite

Test Categories #

  • ✅ Core Operations: SET, GET, DELETE, EXISTS
  • ✅ Advanced Operations: SETEX, TTL, INCR, DECR, KEYS
  • ✅ Connection Management: Connect, disconnect, reconnection
  • ✅ Error Handling: Connection errors, authentication, timeouts
  • ✅ Edge Cases: Empty lists, null responses, invalid inputs
  • ✅ Protocol Testing: All RESP response types (simple strings, bulk strings, integers, arrays)
  • ✅ UTF-8 Support: Cyrillic, Chinese, emoji characters
  • ✅ Validation: Port range validation, parameter validation

Run tests with coverage:

dart test --coverage=coverage
dart pub global activate coverage
dart pub global run coverage:format_coverage --lcov --in=coverage --out=coverage/lcov.info --packages=.dart_tool/package_config.json --report-on=lib

Troubleshooting #

Hanging on first command (e.g. SET) #

Ensure you are using the latest version of the client (RESP formatted with \r\n) and that Redis is reachable at the configured host:port.

Timeout errors #

If responseTimeout is set, reading a response will throw a RedisException when the timeout is exceeded.

Quick Redis start with Docker #

docker run --rm -d -p 6379:6379 --name redis-test redis:alpine

License #

This package is licensed under the MIT License. See the LICENSE file for details.

Contributing #

Contributions are welcome! Please feel free to submit a Pull Request.

2
likes
150
points
24
downloads

Documentation

Documentation
API reference

Publisher

unverified uploader

Weekly Downloads

A simple and lightweight Redis client for Dart.

Repository (GitHub)
View/report issues

License

MIT (license)

More

Packages that depend on redis_dart_client