Search packages, repositories and app categories

GitHub repositoryBlimster/resp_client

resp_client

A RESP (REdis Serialization Protocol) client for Dart.

resp_client project cover
Stars
8
Forks
4
Last push (UTC)
Apr 6, 2021
Project status
Active

Original README

English project snapshot. Visit GitHub for the latest content.

resp_client

A RESP (REdis Serialization Protocol) client for Dart. This package contains 3 libraries. resp_server implements the connectionn to the server, resp_client implements the Redis serialization protocol. resp_commands provides implementations of Redis commands in differents levels of convenience from low-level to easy-to-use.

3 Building blocks

There 3 fundamental building block:

  • RespServerConnection - A connection to a RESP server
  • RespClient - A RESP client connected to a RESP server implementing the request/response model and the RESP types
  • RespCommandsTierN - Implementation of Redis commands

Usage

Initialization and cleanup


import 'package:resp_client/resp_client.dart';
import 'package:resp_client/resp_commands.dart';
import 'package:resp_client/resp_server.dart';

void main(List<String> args) async {
  // create a server connection using sockets
  final server = await connectSocket('localhost');

  // create a client using the server connection
  final client = RespClient(server);

  // create commands of tier 2 using the client
  final commands = RespCommandsTier2(client);

  // execute some commands...

  // close connection to the server
  await server.close();
}

RESP Types

The RESP types are implemented by the classes:

  • RespSimpleString - payload type String
  • RespBulkString - payload type String?
  • RespInteger - payload type int
  • RespArray - payload type List<RespType>?
  • RespError - payload type String

All classes extends the class RestType. You can access the payload of a type using the getter payload.

The class RespType provides methods to convert to a concrete type and getters to check if it is a concrete type.

Use commands

Not all Redis commands are implemented in all tiers yet. Nevertheless, it is possible to execute very Redis command using tier 0. You can create a command object of every tier using a RespClient. It is allowed to create multiple command objects on the same client. Command objects of tier 1 and 2 provides a getter to the underlying tier.

Tier 0

This is the most basic and flexible tier. You can execute every Redis command using this tier. You have to provide a list of elements. All elements are converted to bulk strings using toString(). The result is a RespType. It is up to the user to convert the result to a concrete RESP type.


import 'package:resp_client/resp_server.dart';
import 'package:resp_client/resp_client.dart';
import 'package:resp_client/resp_commands.dart';

void main(List<String> args) async {

  // ... setup connection and client
  
  // create commands using the client
  final commands = RespCommandsTier0(client);

  // execute a command
  final result = await commands.execute(['SET', 'myKey', 'myValue', 'NX']);
  print(result.payload);

  // ... close connection
}

Tier 1

Commands of tier 1 provide some convenience on the parameter side. The user no longer has to build the commands from ground up. Instead, the commands are calle in a more Dart-like style. The result is always a RespType like in tier 0.


import 'package:resp_client/resp_server.dart';
import 'package:resp_client/resp_client.dart';
import 'package:resp_client/resp_commands.dart';

void main(List<String> args) async {

  // ... setup connection and client
  
  // create commands using the client
  final commands = RespCommandsTier1(client);

  // Execute the GET command. You don't have to build the command from ground up.
  // The result is a RespType. This is flexible but you have to convert to the
  // concrete type yourself.
  final result = await commands.get('mKey', 'myValue', mode: SetMode.onlyIfNotExists);
  print(result.toBulkString().payload);

  // ... close connection
}

Tier 2

Commands of tier 2 provide the same convenience on the parameter side as tier 1 commands. Additionally, the result of a command is converted for easy handling.

To convert the result, assumptions are made. As an example the GET command returns a bulk string. Thus, the implementation tries to convert the result from a RespType to a RespBulkString and then return the payload of type String?. But, if a GET command is executed as part of a transaction, the result is a RespSimpleString and the payload has different meaning. Thus, the command will fail. To get out of this, use the same command of the underlying tier.


void main(List<String> args) async {

  // ... setup connection and client
  
  // create commands using the client
  final commands = RespCommandsTier2(client);

  // Like tier 1 commands but the result is already convert.
  // In this case, result is of type String?.
  final result = await commands.get('mKey', 'myValue', mode: SetMode.onlyIfNotExists);
  print(result)

  // ... close connection
}

Oliver Damm GitHub avatar
GitHub author

Oliver Damm ↗

Hamburg, Germany
LanguagesDart

Packages published by this repository

Dependencies used

Dependency list 3 items

  • testDevelopment^1.16.0
  • pedanticDevelopment^1.10.0
  • collectionDevelopment^1.15.0

How do I choose a repository?

Start with your use case, compare repository activity, and check the original project before adopting it.

  1. Search by repository name, owner or description, then narrow the results by topic.
  2. Compare stars, forks and recent pushes. Stars show community interest, not a guarantee of quality.
  3. Read the README, license and issues on GitHub before using a project.

Sources and maintenance

“A repository is the most basic element of GitHub.”

GitHub Docs — About repositories ↗