LogoRevali

Overview

Generate a typed Dart client package for your Revali API, then install, configure and use it

revali_client generates a standalone Dart package that calls your Revali API: one typed method per endpoint, plus a Server class that ties them together. Use it when a Dart or Flutter app talks to your Revali server and you want the calls type-checked against the server's code.

It is a generic construct, so it regenerates on every revali dev run (and on revali build) into .revali/revali_client/.

Installation#

Two packages, both in the server project:

PackageRoleSection
revali_client_gen The construct (code generator) dev_dependencies
revali_client Runtime library the generated code uses; also provides @ExcludeFromClient dependencies
dart pub add revali_client
dart pub add --dev revali_client_gen
pubspec.yaml
dependencies:
  revali_client: ^3.0.1

dev_dependencies:
  revali: ^3.3.3
  revali_client_gen: ^2.5.0

No revali.yaml entry is required. Run the generator:

dart run revali dev

Use the client in an app#

The generated package lives in the server project. Add it to the consuming app as a path dependency, together with revali_client:

my_app/pubspec.yaml
dependencies:
  client: # the generated package's name: `package_name`, default `client`
    path: ../my_server/.revali/revali_client
  revali_client: ^3.0.1

Given a controller on the server:

my_server/routes/controllers/user_controller.dart
import 'package:revali_router/revali_router.dart';

@Controller('users')
class UserController {
  const UserController();

  @Get(':id')
  Future<User> getById(@Param() String id) async => ...;
}

call it from the app:

my_app/lib/main.dart
import 'package:client/client.dart';
import 'package:client/interfaces.dart';

Future<void> main() async {
  final server = Server(baseUrl: Uri.parse('https://api.example.com/api'));

  final UserDataSource users = server.user;
  final user = await users.getById(id: '123');
}
  • package:client/client.dart (named after package_name) holds Server and the implementations.
  • package:client/interfaces.dart holds the ...DataSource interfaces and re-exports Storage.
  • Path, query, header and body parameters become named arguments on the client method. @Cookie parameters are not arguments: the client reads them from storage.

Without baseUrl, Server() calls <scheme>://<host>:<port>/<prefix> taken from your AppConfig at generation time, http://localhost:8080/api by default. Pass baseUrl for anything that is not local development. See Generated Code for everything Server exposes.

Any custom type in a signature must be importable by the app, so keep request and response models in a package both sides depend on. See Sharing types.

Configuration#

Options go under the construct's entry in the server's revali.yaml. All are optional.

revali.yaml
constructs:
  - name: revali_client
    options:
      package_name: my_api_client
      server_name: ApiClient
      scheme: https
      integrations:
        get_it: true
OptionTypeDefaultEffect
package_name String client name: of the generated pubspec.yaml and of its main library, lib/<package_name>.dart . The output directory is always .revali/revali_client/ .
server_name String Server Name of the generated entry class. Must not contain whitespace.
scheme String http Scheme of the default base URL. Has no effect when you pass baseUrl.
integrations.get_it bool false Adds get_it to the generated package and a register(GetIt) method to Server . See get_it .

Excluding endpoints#

@ExcludeFromClient() (or the constant @excludeFromClient) from package:revali_client/revali_client.dart removes a whole controller, or a single method, from the generated client. The server still serves it.

import 'package:revali_client/revali_client.dart';
import 'package:revali_router/revali_router.dart';

@Controller('users')
class UserController {
  const UserController();

  @Get()
  Future<List<User>> getAll() async => ...;

  @ExcludeFromClient()
  @Get('internal/stats')
  Future<UserStats> stats() async => ...;
}

More#

Generated Code · Storage & Cookies · Interceptors, Timeouts & Retries · get_it