Flutter服务集成插件servicestack的使用

发布于 1周前 作者 eggper 来自 Flutter

Flutter服务集成插件servicestack的使用

简介

ServiceStack 的 Add ServiceStack Reference 功能允许客户端通过简单的 x dotnet tool 生成本地类型,从而为您的 ServiceStack 服务提供类型安全的访问。Dart ServiceStack Reference 支持所有 Dart 平台,包括 Flutter 和 AngularDart 或 Dart Web 应用程序,无论是否使用 Dart 2 的强模式。

由于 Dart 缺乏反射和 Mirror 支持,消费 JSON API 在 Flutter 中可能会比较繁琐。但是,我们可以通过生成的 Dart DTO(数据传输对象)和 ServiceStack 的智能通用 JsonServiceClient 来实现与 C# 相同的高效开发体验。

示例用法

1. 安装 x dotnet 工具

首先,安装 .NET Core,然后安装 x dotnet 工具:

$ dotnet tool install --global x
2. 生成 DTO

使用 x dart 命令生成远程 ServiceStack 实例的 DTO,例如:

$ x dart https://techstacks.io

这将生成整个 TechStacks API 的 Dart DTO,并保存到 dtos.dart 文件中。

3. 添加 servicestack 依赖

pubspec.yaml 文件中添加 servicestack 依赖:

dependencies:
  servicestack: ^3.0.0

保存 pubspec.yaml 文件后,VS Code 会自动调用 pub getflutter packages get 来添加新的依赖项。

4. 创建 JsonServiceClient 实例

在 Dart 代码中导入生成的 DTO 和 JsonServiceClient,并创建一个 JsonServiceClient 实例:

import 'package:servicestack/client.dart';
import 'dtos.dart';

void main() async {
  var client = JsonServiceClient.api("https://techstacks.io");

  // 发送请求并获取响应
  var response = await client.get(GetTechnology(slug: "flutter"));
  print("${response.technology.name}: ${response.technology.vendorUrl}");
}

进阶配置

平台中立的使用

为了支持不同平台(如 Flutter 和 Web),可以使用 ClientFactory 来创建 JsonServiceClientJsonWebClient

import 'package:servicestack/web_client.dart' if (dart.library.io) 'package:servicestack/client.dart';

void main() async {
  var client = ClientFactory.api('https://techstacks.io');
  var response = await client.get(GetTechnology(slug: "flutter"));
  print("${response.technology.name}: ${response.technology.vendorUrl}");
}
高级配置

对于更高级的配置,可以使用 ClientConfig.initClient 来初始化所有服务客户端实例,例如配置 JWT 认证:

import 'package:servicestack/client.dart';
import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart';

Future<void> main() async {
  runApp(MyApp());

  ClientConfig.initClient = (client) {
    if (auth != null) {
      client.bearerToken = auth.bearerToken;
      client.refreshToken = auth.refreshToken;
    }
  };

  prefs = await SharedPreferences.getInstance();

  var json = prefs.getString('auth');
  auth = json != null ? AuthenticateResponse.fromJson(jsonDecode(json)) : null;

  client = ClientFactory.apiWith(ClientOptions(
      baseUrl: 'https://dev.servicestack.com:5001', ignoreCert: kDebugMode));
}

完整示例 Demo

项目结构

假设我们有一个名为 HelloFlutter 的 Flutter 项目,项目结构如下:

lib/
  ├── dtos.dart
  ├── test.dtos.dart
  └── main.dart
生成 DTO

lib 目录下运行以下命令生成 DTO:

$ cd lib
$ x dart https://techstacks.io
$ x dart https://test.servicestack.net test
main.dart 代码

以下是 main.dart 的完整代码,展示了如何使用 JsonServiceClient 调用不同的 API:

import 'package:flutter/material.dart';
import 'package:servicestack/client.dart';
import 'test.dtos.dart';
import 'dtos.dart';

const TestBaseUrl = "https://test.servicestack.net";
const TechStacksBaseUrl = "https://techstacks.io";

var testClient = JsonServiceClient.api(TestBaseUrl);
var techstacksClient = JsonServiceClient.api(TechStacksBaseUrl);

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'HelloFlutter',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HelloFlutter(),
    );
  }
}

class HelloFlutter extends StatefulWidget {
  [@override](/user/override)
  State<StatefulWidget> createState() => HelloFlutterState();
}

class HelloFlutterState extends State<HelloFlutter> {
  String result = "";
  Uint8List imageBytes = Uint8List(0);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('HelloFlutter'),
      ),
      body: Column(
        children: <Widget>[
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: <Widget>[
              RaisedButton(
                child: Text("Async"),
                onPressed: () async {
                  var r = await testClient.get(Hello(name: "Async"));
                  setState(() {
                    result = r.result;
                  });
                },
              ),
              RaisedButton(
                child: Text("Auth"),
                onPressed: () async {
                  var auth = await testClient.post(Authenticate(
                      provider: "credentials",
                      userName: "test",
                      password: "test"));

                  var r = await testClient.get(HelloAuth(name: "Auth"));

                  setState(() {
                    result = "${r.result} your JWT is: ${auth.bearerToken}";
                  });
                },
              ),
              RaisedButton(
                child: Text("JWT"),
                onPressed: () async {
                  var auth = await testClient.post(Authenticate(
                      provider: "credentials",
                      userName: "test",
                      password: "test"));

                  var newClient = JsonServiceClient.api(TestBaseUrl)
                    ..refreshToken = auth.refreshToken;

                  var r = await newClient.get(HelloAuth(name: "JWT"));

                  setState(() {
                    result = "${r.result} your RefreshToken is: ${auth.refreshToken}";
                  });
                },
              ),
              RaisedButton(
                child: Text("Query"),
                onPressed: () async {
                  var techs = await techstacksClient.get(FindTechnologies(), args: {"slug": "flutter"});

                  var posts = await techstacksClient.get(QueryPosts(
                      anyTechnologyIds: [techs.results[0].id],
                      types: ['Announcement', 'Showcase'])
                    ..take = 1);

                  setState(() {
                    result = "Latest Flutter Announcement:\n“${posts.results[0].title}”";
                  });
                },
              ),
              RaisedButton(
                child: Text("Batch"),
                onPressed: () async {
                  var requests = ['foo', 'bar', 'qux'].map((name) => Hello(name: name));

                  var responses = await testClient.sendAll(requests);

                  setState(() {
                    result = "Batch Responses:\n${responses.map((r) => r.result).join('\n')}";
                  });
                },
              ),
              RaisedButton(
                child: Text("Image"),
                onPressed: () async {
                  Uint8List bytes = await testClient.get(HelloImage(
                      name: "Flutter",
                      fontFamily: "Roboto",
                      background: "#0091EA",
                      width: 500,
                      height: 170));

                  setState(() {
                    result = "";
                    imageBytes = bytes;
                  });
                },
              ),
            ],
          ),
          result != null && result != ""
              ? Text(result)
              : Image.memory(imageBytes, width: 500.0, height: 170.0),
        ],
      ),
    );
  }
}

更多关于Flutter服务集成插件servicestack的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter服务集成插件servicestack的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中集成并使用servicestack插件的示例代码。servicestack插件通常用于在Flutter应用中与原生服务进行交互,但请注意,由于servicestack并非一个广为人知的通用Flutter插件(可能是一个自定义或特定组织的插件),以下代码会基于一个假设的插件API结构。如果servicestack有特定的官方文档或GitHub仓库,请参考那些资源以获取准确的集成和使用指南。

假设servicestack插件提供了一个基本的接口来调用原生服务,我们可以按照以下步骤进行集成:

  1. 添加依赖: 首先,在你的pubspec.yaml文件中添加servicestack插件的依赖(注意:这里的依赖名和版本号是假设的,你需要根据实际的插件信息来填写)。

    dependencies:
      flutter:
        sdk: flutter
      servicestack: ^0.1.0  # 假设的版本号
    
  2. 导入插件: 在你的Dart文件中导入servicestack插件。

    import 'package:servicestack/servicestack.dart';
    
  3. 初始化插件: 通常,插件需要在应用启动时进行初始化。你可以在MainActivity.kt(Android)或AppDelegate.swift(iOS)中进行初始化,但由于我们假设servicestack提供了Dart端的初始化方法,这里直接在Dart代码中初始化。

    void main() {
      WidgetsFlutterBinding.ensureInitialized();
      // 假设存在一个初始化方法
      ServiceStack.instance.init();
      runApp(MyApp());
    }
    
  4. 调用服务: 使用servicestack插件提供的API来调用原生服务。以下是一个假设的调用原生服务的示例:

    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          home: Scaffold(
            appBar: AppBar(
              title: Text('ServiceStack Example'),
            ),
            body: Center(
              child: ElevatedButton(
                onPressed: () async {
                  try {
                    // 假设有一个调用原生服务的方法
                    var result = await ServiceStack.instance.callService('exampleService', {
                      'param1': 'value1',
                      'param2': 123,
                    });
                    print('Service call result: $result');
                  } catch (e) {
                    print('Service call failed: $e');
                  }
                },
                child: Text('Call Service'),
              ),
            ),
          ),
        );
      }
    }
    
  5. 原生代码实现(如果需要): 如果servicestack需要你在原生代码中实现服务逻辑,你需要在Android的MainActivity.ktMainActivity.java以及iOS的AppDelegate.swift或相应的Swift/Objective-C文件中添加相应的代码。但由于这取决于插件的具体实现,这里不提供具体的原生代码示例。

注意

  • 上述代码是一个基于假设的示例,实际的servicestack插件可能有不同的API和初始化方法。
  • 请务必查阅servicestack插件的官方文档或GitHub仓库以获取准确的集成和使用指南。
  • 如果servicestack是一个私有或内部使用的插件,你可能需要联系插件的开发者或维护者以获取更多信息和支持。
回到顶部