Skip to content

Commit

Permalink
release validation and update docs (#93)
Browse files Browse the repository at this point in the history
* update docs and validation

* preparing release for core 2.0.0-alpha.6
  • Loading branch information
necessarylion authored Dec 27, 2023
1 parent 060ecb7 commit caa1c7b
Show file tree
Hide file tree
Showing 24 changed files with 233 additions and 365 deletions.
154 changes: 0 additions & 154 deletions docs/digging-deeper/cache.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,157 +84,3 @@ await Cache().store('file').put('foo', 'bar');

!!! info
If you have multiple drivers, you can use `store()` method to set the driver name. By default it will be `file` driver.

## Custom Drivers

To create a custom driver, you have the option to implement the `CacheDriverInterface`. See sample below for redis driver.

### Redis Driver

=== "1. Crete redis service"

```dart
import 'package:dox_core/dox_core.dart';
import 'package:redis/redis.dart';

class Redis implements DoxService {
/// Declare as Singleton to reuse connection
static final Redis _i = Redis._internal();
factory Redis() => _i;
Redis._internal();

late Command command;

@override
Future<void> setup() async {
RedisConnection conn = RedisConnection();
String tls = Env.get('REDIS_TLS', 'false');
String host = Env.get('REDIS_HOST', 'localhost');
int port = int.parse(Env.get('REDIS_PORT', '6379'));

if (tls == 'true') {
Redis().command = await conn.connectSecure(host, port);
} else {
Redis().command = await conn.connect(host, port);
}

String username = Env.get('REDIS_USERNAME', '');
String password = Env.get('REDIS_PASSWORD', '');

if (username.isNotEmpty && password.isNotEmpty) {
await Redis().command.send_object(
<dynamic>['AUTH', username, password],
);
}
}
}
```


=== "2. Register in dox"

```dart
void main() async {
/// Initialize Dox
Dox().initialize(Config());
...

/// register redis connection
Dox().addService(Redis());

...
/// start dox http server
await Dox().startServer();
}

```

=== "3. Create redis driver"

```dart
import 'package:dox_core/cache/cache_driver_interface.dart';
import 'package:redis/redis.dart';

import '../config/redis.dart';

class RedisCacheDriver implements CacheDriverInterface {
@override
String tag = '';

@override
String get prefix => 'dox-framework-cache-$tag:';

RedisCacheDriver();

@override
void setTag(String tagName) {
tag = tagName;
}

@override
Future<void> flush() async {
Command cmd = Redis().command;
List<dynamic> res = await cmd.send_object(<dynamic>['KEYS', '$prefix*']);
if (res.isNotEmpty) {
await cmd.send_object(<dynamic>['DEL', ...res]);
}
}

@override
Future<void> forever(String key, String value) async {
await put(key, value, duration: Duration(days: 365 * 1000));
}

@override
Future<void> forget(String key) async {
Command cmd = Redis().command;
return await cmd.send_object(<dynamic>['DEL', prefix + key]);
}

@override
Future<dynamic> get(String key) async {
Command cmd = Redis().command;
return await cmd.send_object(<dynamic>['GET', prefix + key]);
}

@override
Future<bool> has(String key) async {
dynamic val = await get(key);
return val != null ? true : false;
}

@override
Future<void> put(String key, String value, {Duration? duration}) async {
duration = duration ?? Duration(hours: 1);
DateTime time = DateTime.now().add(duration);

Command cmd = Redis().command;

await cmd.send_object(<dynamic>[
'SET',
prefix + key,
value,
'PXAT',
time.millisecondsSinceEpoch,
]);
}
}
```

=== "4. Register redis driver"

```dart

/// register redis cache driver in `lib/config/app.dart`
@override
CacheConfig get cacheConfig => CacheConfig(
defaultDriver: 'redis',
drivers: <String, CacheDriverInterface>{
'file': FileCacheDriver(),
'redis': RedisCacheDriver(),
},
);
```

!!! info
See more detail about Dox services [here](services.md).
2 changes: 1 addition & 1 deletion docs/digging-deeper/dox-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ dox build_runner:build

```py
dox build (compile into machine code)
bin/dox (run exec file to serve http server)
bin/server (run exec file to serve http server)
```

## Generate app key
Expand Down
18 changes: 16 additions & 2 deletions docs/digging-deeper/env.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,22 @@ Dox allows you to access the environment variables from `.env` using `Env` class
=== "Example"

```dart
Evn.get('APP_KEY');
Env.get('APP_KEY');

// With default values
Evn.get('APP_KEY', 'default_value');
Env.get('APP_KEY', 'default_value');
```

## With type

=== "Int"

```dart
Env.get<int>('APP_PORT', 3000)
```

=== "String"

```dart
Env.get<String>('APP_KEY')
```
12 changes: 4 additions & 8 deletions docs/digging-deeper/isolate.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,9 @@

Dox support multi-threaded HTTP server using isolates that can handle 10x concurrency requests with high speed.

```dart
class Config extends AppConfig {
@override
int get totalIsolate => 3;
By default, Dox runs on three isolates. You can configure this setting in the `lib/config/app.dart` file. Or simply add like `APP_TOTAL_ISOLATE=6` in environment variable.

...
}
```

By default, Dox runs on three isolates. You can configure this setting in the `lib/config/app.dart` file.
```dart
totalIsolate: Env.get<int>('APP_TOTAL_ISOLATE', 6),
```
70 changes: 27 additions & 43 deletions docs/digging-deeper/services.md
Original file line number Diff line number Diff line change
@@ -1,57 +1,41 @@
# Services

If your application requires additional services like a database or Redis, you'll need to create a class that implements the `DoxService` interface and then register it with Dox. Since Dox operates with isolates (multi-threading), these extra services must be passed to each isolate to ensure their availability on all isolates.
If your application requires additional services like a database, auth etc.., you'll need to create a class that implements the `DoxService` interface and then register it with Dox. Since Dox operates with isolates (multi-threading), these extra services must be passed to each isolate to ensure their availability on all isolates.

### Example with redis
### Example with auth

=== "Redis service"
=== "AuthService"

```dart
class Redis implements DoxService {
/// Declare as Singleton reuse connection
static final Redis _i = Redis._internal();
factory Redis() => _i;
Redis._internal();

late Command command;

class AuthService implements DoxService {
@override
Future<void> setup() async {
RedisConnection conn = RedisConnection();
String tls = Env.get('REDIS_TLS', 'false');
String host = Env.get('REDIS_HOST', 'localhost');
int port = int.parse(Env.get('REDIS_PORT', '6379'));

if (tls == 'true') {
Redis().command = await conn.connectSecure(host, port);
} else {
Redis().command = await conn.connect(host, port);
}

String username = Env.get('REDIS_USERNAME', '');
String password = Env.get('REDIS_PASSWORD', '');

if (username.isNotEmpty && password.isNotEmpty) {
await Redis().command.send_object(
<dynamic>['AUTH', username, password],
);
}
void setup() {
Auth.initialize(AuthConfig(
/// default auth guard
defaultGuard: 'web',

/// list of auth guards
guards: <String, AuthGuard>{
'web': AuthGuard(
driver: JwtAuthDriver(secret: SecretKey(Env.get('APP_KEY'))),
provider: AuthProvider(
model: () => User(),
),
),
},
));
}
}
```

#####
=== "Register into dox `bin/server.dart`"
=== "Register into dox `app/config/services.dart`"

```dart
void main() async {
/// Initialize Dox
Dox().initialize(Config());
```dart
List<DoxService> services = <DoxService>[
... /// other services
AuthService,
];
```

/// register redis service
Dox().addService(Redis());

/// start dox http server
await Dox().startServer();
}
```

6 changes: 4 additions & 2 deletions docs/digging-deeper/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
## Integration test

```dart
import 'package:dox_app/config/app.dart';
import 'package:dox_core/dox_core.dart';
import 'package:http/http.dart' as http;
import 'package:test/test.dart';
Config config = Config();
String baseUrl = 'http://localhost:${config.serverPort}';
void main() {
setUpAll(() async {
Dox().initialize(config);
Dox().initialize(appConfig);
await Dox().startServer();
// for for few seconds to fully started http server
Expand Down
17 changes: 7 additions & 10 deletions docs/digging-deeper/websocket.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,15 @@ class WebsocketService implements DoxService {
```

!!! info
While running with multiple isolate(multithread), the Dox WebSocket require Redis adapter which require [`ioredis`](https://pub.dev/packages/ioredis) package to function. Currently, Dox WebSocket only supports the Redis adapter. And if you do not want to use any adapter, please set total isolate value to 1 `int get totalIsolate => 1` in `lib/config/app.dart` to function properly.
While running with multiple isolate(multithread), the Dox WebSocket require Redis adapter which require [`ioredis`](https://pub.dev/packages/ioredis) package to function. Currently, Dox WebSocket only supports the Redis adapter. And if you do not want to use any adapter, please set total isolate value to `1` in `lib/config/app.dart` to function properly.

### 2. Register websocket service to dox
### 2. Register websocket service to dox `app/config/services.dart`

```dart
/// bin/server.dart
....
Dox().addService(WebsocketService());
....
await Dox().startServer();
List<DoxService> services = <DoxService>[
... /// other services
WebsocketService,
];
```

### 3. Create websocket controller
Expand Down Expand Up @@ -63,7 +60,7 @@ class ChatWebSocketController {
!!! tip "Note"
As webSocket maintains an open connection, there is no requirement to send back any values from your controller method.

### 4. register websocket route
### 4. register websocket route and events

```dart
ChatWebSocketController controller = ChatWebSocketController();
Expand Down
Loading

0 comments on commit caa1c7b

Please sign in to comment.