or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mdindex.mdredis-service.mdservice-factory.md

redis-service.mddocs/

0

# Redis Service

1

2

The RedisService provides the primary interface for Redis operations in Midway.js applications through dependency injection. It wraps the default Redis client instance and delegates all ioredis methods, providing seamless access to Redis functionality.

3

4

## Capabilities

5

6

### RedisService Class

7

8

Main service wrapper implementing the full Redis interface through method delegation.

9

10

```typescript { .api }

11

/**

12

* Primary Redis service for dependency injection

13

* Implements the full ioredis Redis interface

14

* Automatically connects to the default Redis client

15

*/

16

class RedisService implements Redis {

17

@Inject()

18

private serviceFactory: RedisServiceFactory;

19

20

private instance: Redis;

21

22

@Init()

23

async init(): Promise<void>;

24

25

defineCommand(

26

name: string,

27

definition: {

28

lua: string;

29

numberOfKeys?: number;

30

readOnly?: boolean;

31

}

32

): void;

33

}

34

35

interface RedisService extends Redis {}

36

```

37

38

### Service Initialization

39

40

Automatically initializes with the default Redis client from the service factory.

41

42

```typescript { .api }

43

/**

44

* Initializes the service with default Redis client

45

* Called automatically by Midway.js during dependency injection

46

* @throws MidwayCommonError if default Redis instance not found

47

*/

48

async init(): Promise<void>;

49

```

50

51

### Custom Command Definition

52

53

Defines custom Redis commands using Lua scripts.

54

55

```typescript { .api }

56

/**

57

* Defines a custom Redis command using Lua scripting

58

* The command becomes available as a method on the service

59

* @param name - Name of the custom command

60

* @param definition - Command definition with Lua script

61

*/

62

defineCommand(

63

name: string,

64

definition: {

65

lua: string;

66

numberOfKeys?: number;

67

readOnly?: boolean;

68

}

69

): void;

70

```

71

72

**Usage Examples:**

73

74

```typescript

75

import { RedisService } from "@midwayjs/redis";

76

import { Inject, Provide } from "@midwayjs/core";

77

78

@Provide()

79

export class CacheService {

80

@Inject()

81

redisService: RedisService;

82

83

async init() {

84

// Define a custom atomic increment with expire command

85

this.redisService.defineCommand('incrWithExpire', {

86

lua: `

87

local current = redis.call('INCR', KEYS[1])

88

if current == 1 then

89

redis.call('EXPIRE', KEYS[1], ARGV[1])

90

end

91

return current

92

`,

93

numberOfKeys: 1,

94

readOnly: false,

95

});

96

}

97

98

async incrementCounter(key: string, expireSeconds: number) {

99

// Use the custom command (TypeScript may need type assertion)

100

return (this.redisService as any).incrWithExpire(key, expireSeconds);

101

}

102

}

103

```

104

105

## Redis Operations

106

107

The RedisService implements the complete ioredis interface, providing access to all Redis commands and operations:

108

109

### String Operations

110

111

```typescript

112

// All string operations from ioredis are available

113

await redisService.set('key', 'value');

114

await redisService.get('key');

115

await redisService.setex('key', 60, 'value'); // Set with expiration

116

await redisService.incr('counter');

117

await redisService.mget(['key1', 'key2', 'key3']);

118

```

119

120

### Hash Operations

121

122

```typescript

123

await redisService.hset('user:123', 'name', 'John');

124

await redisService.hget('user:123', 'name');

125

await redisService.hmset('user:123', { name: 'John', age: 30 });

126

await redisService.hgetall('user:123');

127

```

128

129

### List Operations

130

131

```typescript

132

await redisService.lpush('queue', 'task1');

133

await redisService.rpop('queue');

134

await redisService.lrange('queue', 0, -1);

135

```

136

137

### Set Operations

138

139

```typescript

140

await redisService.sadd('tags', 'redis', 'database');

141

await redisService.smembers('tags');

142

await redisService.sismember('tags', 'redis');

143

```

144

145

### Sorted Set Operations

146

147

```typescript

148

await redisService.zadd('leaderboard', 100, 'player1');

149

await redisService.zrange('leaderboard', 0, 9);

150

await redisService.zrevrange('leaderboard', 0, 9, 'WITHSCORES');

151

```

152

153

### Key Management

154

155

```typescript

156

await redisService.exists('key');

157

await redisService.expire('key', 3600);

158

await redisService.ttl('key');

159

await redisService.del('key1', 'key2');

160

await redisService.keys('pattern*');

161

```

162

163

## Usage Examples

164

165

### Basic Operations

166

167

```typescript

168

import { RedisService } from "@midwayjs/redis";

169

import { Inject, Provide } from "@midwayjs/core";

170

171

@Provide()

172

export class UserService {

173

@Inject()

174

redisService: RedisService;

175

176

async cacheUser(userId: string, userData: any) {

177

const key = `user:${userId}`;

178

await this.redisService.setex(key, 3600, JSON.stringify(userData));

179

}

180

181

async getUser(userId: string) {

182

const key = `user:${userId}`;

183

const cached = await this.redisService.get(key);

184

return cached ? JSON.parse(cached) : null;

185

}

186

187

async deleteUser(userId: string) {

188

const key = `user:${userId}`;

189

await this.redisService.del(key);

190

}

191

}

192

```

193

194

### Session Management

195

196

```typescript

197

@Provide()

198

export class SessionService {

199

@Inject()

200

redisService: RedisService;

201

202

async createSession(sessionId: string, userData: any, ttlSeconds = 1800) {

203

const key = `session:${sessionId}`;

204

await this.redisService.setex(key, ttlSeconds, JSON.stringify(userData));

205

}

206

207

async getSession(sessionId: string) {

208

const key = `session:${sessionId}`;

209

const data = await this.redisService.get(key);

210

return data ? JSON.parse(data) : null;

211

}

212

213

async refreshSession(sessionId: string, ttlSeconds = 1800) {

214

const key = `session:${sessionId}`;

215

await this.redisService.expire(key, ttlSeconds);

216

}

217

218

async destroySession(sessionId: string) {

219

const key = `session:${sessionId}`;

220

await this.redisService.del(key);

221

}

222

}

223

```

224

225

### Rate Limiting

226

227

```typescript

228

@Provide()

229

export class RateLimitService {

230

@Inject()

231

redisService: RedisService;

232

233

async checkRateLimit(

234

identifier: string,

235

maxRequests: number,

236

windowSeconds: number

237

): Promise<{ allowed: boolean; remaining: number }> {

238

const key = `rate_limit:${identifier}`;

239

const current = await this.redisService.incr(key);

240

241

if (current === 1) {

242

await this.redisService.expire(key, windowSeconds);

243

}

244

245

const remaining = Math.max(0, maxRequests - current);

246

return {

247

allowed: current <= maxRequests,

248

remaining

249

};

250

}

251

}

252

```

253

254

## Event Handling

255

256

The RedisService supports all ioredis event handling:

257

258

```typescript

259

@Provide()

260

export class MonitorService {

261

@Inject()

262

redisService: RedisService;

263

264

async init() {

265

// Listen for connection events

266

this.redisService.on('connect', () => {

267

console.log('Redis connected');

268

});

269

270

this.redisService.on('error', (error) => {

271

console.error('Redis error:', error);

272

});

273

274

this.redisService.on('close', () => {

275

console.log('Redis connection closed');

276

});

277

}

278

}

279

```

280

281

## Transaction Support

282

283

Full support for Redis transactions and pipelines:

284

285

```typescript

286

async transferBetweenCounters(from: string, to: string, amount: number) {

287

const multi = this.redisService.multi();

288

multi.decrby(from, amount);

289

multi.incrby(to, amount);

290

291

const results = await multi.exec();

292

return results;

293

}

294

295

// Pipeline for bulk operations

296

async bulkSet(keyValuePairs: Record<string, string>) {

297

const pipeline = this.redisService.pipeline();

298

299

Object.entries(keyValuePairs).forEach(([key, value]) => {

300

pipeline.set(key, value);

301

});

302

303

await pipeline.exec();

304

}

305

```