{"id":20874972,"url":"https://github.com/servicestack/servicestack-dart","last_synced_at":"2025-07-21T18:35:21.447Z","repository":{"id":49110318,"uuid":"128577633","full_name":"ServiceStack/servicestack-dart","owner":"ServiceStack","description":"Dart servicestack client pub","archived":false,"fork":false,"pushed_at":"2024-12-13T07:39:13.000Z","size":2253,"stargazers_count":8,"open_issues_count":0,"forks_count":7,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-07-18T04:04:14.511Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Dart","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ServiceStack.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-04-07T23:39:39.000Z","updated_at":"2024-12-14T15:35:14.000Z","dependencies_parsed_at":"2024-11-11T11:21:02.099Z","dependency_job_id":"d3df5e33-a0d6-4a8e-b5ee-2af265e3ee04","html_url":"https://github.com/ServiceStack/servicestack-dart","commit_stats":{"total_commits":173,"total_committers":9,"mean_commits":19.22222222222222,"dds":0.06358381502890176,"last_synced_commit":"c3f1b32b3d3039159465e57635aeabc07de7df56"},"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/ServiceStack/servicestack-dart","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ServiceStack%2Fservicestack-dart","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ServiceStack%2Fservicestack-dart/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ServiceStack%2Fservicestack-dart/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ServiceStack%2Fservicestack-dart/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ServiceStack","download_url":"https://codeload.github.com/ServiceStack/servicestack-dart/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ServiceStack%2Fservicestack-dart/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266352734,"owners_count":23915810,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-21T11:47:31.412Z","response_time":64,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-18T06:40:36.197Z","updated_at":"2025-07-21T18:35:21.425Z","avatar_url":"https://github.com/ServiceStack.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Dart Banner](https://raw.githubusercontent.com/ServiceStack/docs/master/docs/images/dart/dart.png)\n\nServiceStack's **Add ServiceStack Reference** feature allows clients to generate Native Types from a simple [x dotnet tool](https://docs.servicestack.net/dotnet-tool)  - providing a simple way to give clients typed access to your ServiceStack Services.\n\n### Dart ServiceStack Reference\n\nDart ServiceStack Reference supports **all Dart platforms**, including Flutter and AngularDart or Dart Web Apps with and without Dart 2's Strong Mode - in the same optimal development workflow pioneered in [Add ServiceStack Reference](https://docs.servicestack.net/add-servicestack-reference) where it doesn't requiring any additional tooling, transformers or build steps. \n\nDue to the lack of reflection and Mirror support, consuming JSON APIs can be quite [cumbersome in Flutter](https://flutter.io/cookbook/networking/fetch-data/). But we've been able to achieve the same productive development experience available in [all supported languages](https://docs.servicestack.net/add-servicestack-reference) where you can use the generated Dart DTOs from any remote v5.1+ ServiceStack endpoint with ServiceStack's Smart generic\n[JsonServiceClient](https://pub.dartlang.org/documentation/servicestack/latest/servicestack/JsonServiceClient-class.html) available in the [servicestack Dart package](https://pub.dartlang.org/packages/servicestack#-installing-tab-), to enable an end-to-end Typed API for calling Services by [sending and receiving native DTOs](https://docs.servicestack.net/architecture-overview#client-architecture).\n\n### Example Usage\n\nYou can use the same [x dotnet tool](https://docs.servicestack.net/dotnet-tool) simple command-line utility to easily Add and Update ServiceStack References for all supported languages:\n\nInstall [.NET Core](https://dotnet.microsoft.com/download) then install the `x` dotnet tool:\n\n    $ dotnet tool install --global x\n\nYou can then execute `x dart` with the URL of the remote ServiceStack Instance you want to generated DTOs for, e.g:\n\n    $ x dart https://techstacks.io\n\nThis will generate Dart DTOs for the [entire TechStacks API](https://techstacks.io/metadata):\n\n    Saved to: dtos.dart\n\n\u003e If no name is specified in the 2nd argument, it uses `dtos` if it doesn't exist, otherwise falls back to infer it from the URL.\n\nTo make API calls we need to use the `JsonServiceClient`, installed by adding the [servicestack](https://pub.dartlang.org/packages/servicestack#-installing-tab-) package to our Dart projects `pubspec.yaml`:\n\n```yaml\ndependencies:\n  servicestack: ^3.0.0\n```\n\nThis requires Dart DTOs generated from ServiceStack **v5.11.1+** that's [now available on MyGet](https://docs.servicestack.net/myget).\n\nSaving `pubspec.yaml` in VS Code with the [Dart Code Extension](https://dartcode.org) automatically calls `pub get` or `flutter packages get` (in Flutter projects) to add any new dependencies to your project.\n\nWe now have everything we need to be able to make typed API requests to any of [TechStacks APIs](https://techstacks.io/metadata) with a shared `JsonServiceClient` instance populated with the base URL of the remote endpoint, e.g:\n\n```dart\nimport 'package:servicestack/client.dart';\n\nimport 'dtos.dart';\n\nvar client = JsonServiceClient.api(\"https://techstacks.io\");\n\nmain() async {\n  var response = await client.get(GetTechnology(slug: \"flutter\"));\n  print(\"${response.technology.name}: ${response.technology.vendorUrl}\");\n}\n```\n\nLike C#, Dart has Generics and Type Inference so the `response` returned is the typed `HelloResponse` DTO giving us rich intelli-sense and compiler type safety. \n\n#### Issues\n\nPlease submit issues to [github.com/ServiceStack/Issues](https://github.com/ServiceStack/Issues).\n\n### Platform neutral usage\n\nBoth **dart:io** `JsonServiceClient` and **dart:html** `JsonWebClient` implement the same shared `IServiceClient` interface which support a platform-neutral source-compatible API using the\n`ClientFactory` APIs, e.g: \n\n```dart\nimport 'package:servicestack/web_client.dart' if (dart.library.io) 'package:servicestack/client.dart';\n\nmain() async {\n  var client = ClientFactory.api('https://techstacks.io');\n  var response = await client.get(GetTechnology(slug: \"flutter\"));\n  print(\"${response.technology.name}: ${response.technology.vendorUrl}\");\n}\n```\n\nFor advanced configuration you can use the `createWith(ClientOptions)` API, e.g you can use `dev.servicestack.com` which resolves to `10.0.2.2` \nwhich in Android you can use to access `127.0.0.1` of the host OS allowing you to access your local development server.\n\nIn this example we'll create either a typed Service Client to our local development server in **Debug** during development (ignoring its self-signed certificate)\nand our production server in **Release** mode: \n\n```dart\nimport 'package:servicestack/web_client.dart' if (dart.library.io) 'package:servicestack/client.dart';\nimport 'package:flutter/foundation.dart';\n\nmain() async {\n  var client = kDebugMode\n    ? ClientFactory.apiWith(ClientOptions(baseUrl:'https://dev.servicestack.com:5001', ignoreCert:true))\n    : ClientFactory.api('https://techstacks.io');\n}\n```\n\n\u003e Tip: if you add a `127.0.0.1 dev.servicestack.com` mapping in your OS's `hosts` file you'll also be able to use `dev.servicestack.com` to access your local dev server in your Host OS. \n\n### Shared Initialization Configuration\n\nFor more advanced configuration you can use the `ClientConfig.initClient` client factory filter to customize all service client instances \nas done in this example to configure all client instances with any previously saved JWT Bearer \u0026 Refresh Tokens to enable authenticated access:\n\n```dart\nSharedPreferences prefs;\nIServiceClient client;\nAuthenticateResponse auth;\n\nFuture\u003cvoid\u003e main() async {\n  runApp(MyApp());\n\n  ClientConfig.initClient = (client) {\n    if (auth != null) {\n      client.bearerToken = auth.bearerToken;\n      client.refreshToken = auth.refreshToken;\n    }\n  };\n\n  prefs = await SharedPreferences.getInstance();\n\n  var json = prefs.getString('auth');\n  auth = json != null\n      ? AuthenticateResponse.fromJson(jsonDecode(json))\n      : null;\n\n  client = ClientFactory.apiWith(ClientOptions(\n      baseUrl:'https://dev.servicestack.com:5001', ignoreCert:kDebugMode));\n}\n```\n\n### JsonWebClient\n\nFor browser projects you can use the `JsonWebClient` from `web_client.dart` directly, e.g:\n\n```dart\nimport 'package:servicestack/web_client.dart';\n\nvar client = JsonWebClient.api(\"https://techstacks.io\");\n```\n\nThe `JsonWebClient` performs HTTP Requests using [dart:html BrowserClient](https://webdev.dartlang.org/angular/guide/server-communication) to use the browsers built-in `XMLHttpRequest` object. Despite their implementation differences `JsonWebClient` also supports the same feature-set as the Dart VM's `JsonServiceClient` above. \n\n#### Concrete-specific functionality\n\nIn addition to implementing the `IServiceClient` above, each Service Client includes additional concrete specific functionality allowing for finer-grained access to their underlying HTTP Clients, \ne.g. as the Request/Response filters have different Type signatures (dart:io's `HttpClientResponse` vs Browser's `Response`) they can't be declared in the shared `IServiceClient` interface, but thanks to Dart's type inference many of the extended concrete APIs are still source-compatible, e.g:\n\n```dart\nvar vmClient = JsonServiceClient.api(baseUrl)\n    ..responseFilter = (res) =\u003e print(res.headers[\"X-Args\"]);\n\nvar webClient = JsonWebClient.api(baseUrl)\n    ..responseFilter = (res) =\u003e print(res.headers[\"X-Args\"]);\n```\n\n### Rich Generated Models\n\nThanks to the direct C# to Dart model code generation we're able to create the ideal idiomatic message-based APIs utilizing rich typed models with broad support for many of the C#/.NET features used when defining DTOs inc. Generics, Inheritance, multiple Interfaces, Enums (inc. int and Flag Enums), Tuples, metadata Attributes emitted in comments (emitting additional documentation in the generated models) whilst also taking care of mapping built-in C# Types like `DateTime`, `TimeSpan`, `byte[]` and `Stream` into their equivalent native Dart [DateTime](https://api.dartlang.org/stable/1.24.3/dart-core/DateTime-class.html), [Duration](https://api.dartlang.org/stable/1.24.3/dart-core/Duration-class.html) and [Uint8List](https://api.dartlang.org/stable/1.24.3/dart-typed_data/Uint8List-class.html) types, C# generic collections are also converted into their equivalent Dart generic collection Type.\n\n\n#### JsonCodec compatible\n\nThe generated DTOs follow Dart's [JsonCodec](https://api.dartlang.org/stable/1.24.3/dart-convert/JsonCodec-class.html) pattern allowing them to be individually serializable with Dart's universal JSON encode/decode APIs, e.g:\n\n```dart\n//Serialization\nvar dto = MyDto(name:\"foo\");\nString jsonString = json.encode(dto);\n\n//Deserialization\nMap\u003cString,dynamic\u003e jsonObj = json.decode(jsonString);\nvar fromJson = MyDto.fromJson(jsonObj);\n```\n\n#### Default Constructor\n\nAll DTOs also include a default constructor containing all properties as optional arguments providing a wrist-friendly syntax for creating and populating DTOs in a single constructor expression, e.g:\n\n```dart\nvar request = MyDto(name:\"foo\");\n```\n\nOnly the properties of each DTO are included in its default constructor so you'll need to use property accessors to initialize any fields in base classes, but thanks to Dart's support for method cascades you can still populate an entire DTO with a single expression, e.g:\n\n```dart\nvar request = FindTechnologies(name:\"Flutter\")\n    ..fields = \"id,slug,vendorName,productUrl\"\n    ..orderBy = \"created,-viewCount\"\n    ..take = 1;\n```\n\n#### IConvertible\n\nAll DTOs implement the `IConvertible` interface below where each instance can be converted to and from a Map of values, giving each model dynamism that's otherwise not possible in Flutter:\n\n```csharp\nabstract class IConvertible\n{\n    TypeContext context;\n    fromMap(Map\u003cString, dynamic\u003e map);\n    Map\u003cString, dynamic\u003e toJson();\n}\n```\n\nThe conversion logic that handles the behind-the-scenes conversion into and out of Dart Types is maintained in the extensible [JsonConverters](https://pub.dartlang.org/documentation/servicestack/latest/servicestack/JsonConverters/Converters.html) class which lets you replace built-in converters with your own implementation or register new Converters when you want to take over handling of specific types.\n\n### JsonServiceClient\n\nThe `JsonServiceClient` is a smart full-featured Service Client implementation with a number of high-level features that make consuming ServiceStack APIs a seamless experience, with built-in support for:\n\n - HTTP Basic Auth (inc. [API Key support](https://docs.servicestack.net/api-key-authprovider))\n - [Cookies, Sessions and Credential Auth](https://docs.servicestack.net/sessions)\n - [JWT, including using RefreshTokens to auto-fetch new JWT Bearer Tokens](https://docs.servicestack.net/jwt-authprovider)\n - [Structured Error Handling](https://docs.servicestack.net/error-handling)\n - [Auto Batched Requests](https://docs.servicestack.net/auto-batched-requests)\n - Global and per-instance Request, Response and Exception Filters\n - `onAuthenticationRequired` hook to handle re-authentication and transparent replay of failed 401 requests\n\nBehind the scenes `JsonServiceClient` leverages the optimal [`HttpClient` in dart:io](https://docs.flutter.io/flutter/dart-io/HttpClient-class.html) to perform HTTP Requests in Flutter and Dart VM Apps.\n\n### IServiceClient API\n\nBoth JSON Service Client variants implement the same flexible `IServiceClient` API below, use the same DTOs and implementation and throws the same structured `WebServiceException` which results in Typed API Requests being source-compatible between Dart Web Apps, Dart VM Server and AOT compiled Flutter Web Apps:\n\n```csharp\nabstract class IServiceClient {\n  String baseUrl;\n  String bearerToken;\n  String refreshToken;\n  String userName;\n  String password;\n\n  Future\u003cApiResult\u003cT\u003e\u003e api\u003cT\u003e(IReturn\u003cT\u003e request,\n      {Map\u003cString, dynamic\u003e? args, String? method});\n\n  Future\u003cApiResult\u003cEmptyResponse\u003e\u003e apiVoid(IReturnVoid request,\n      {Map\u003cString, dynamic\u003e? args, String? method});\n\n  Future\u003cT\u003e get\u003cT\u003e(IReturn\u003cT\u003e request, {Map\u003cString, dynamic\u003e args});\n  Future\u003cMap\u003cString, dynamic\u003e\u003e getUrl(String path, {Map\u003cString, dynamic\u003e args});\n  Future\u003cT\u003e getAs\u003cT\u003e(String path, {Map\u003cString, dynamic\u003e args, T responseAs});\n\n  Future\u003cT\u003e post\u003cT\u003e(IReturn\u003cT\u003e request, {dynamic body, Map\u003cString, dynamic\u003e args});\n  Future\u003cMap\u003cString, dynamic\u003e\u003e postToUrl(String path, dynamic body, {Map\u003cString, dynamic\u003e args});\n  Future\u003cT\u003e postAs\u003cT\u003e(String path, dynamic body, {Map\u003cString, dynamic\u003e args, T responseAs});\n\n  Future\u003cT\u003e delete\u003cT\u003e(IReturn\u003cT\u003e request, {Map\u003cString, dynamic\u003e args});\n  Future\u003cMap\u003cString, dynamic\u003e\u003e deleteUrl(String path, {Map\u003cString, dynamic\u003e args});\n  Future\u003cT\u003e deleteAs\u003cT\u003e(String path, {Map\u003cString, dynamic\u003e args, T responseAs});\n\n  Future\u003cT\u003e put\u003cT\u003e(IReturn\u003cT\u003e request, {dynamic body, Map\u003cString, dynamic\u003e args});\n  Future\u003cMap\u003cString, dynamic\u003e\u003e putToUrl(String path, dynamic body, {Map\u003cString, dynamic\u003e args});\n  Future\u003cT\u003e putAs\u003cT\u003e(String path, dynamic body, {Map\u003cString, dynamic\u003e args, T responseAs});\n\n  Future\u003cT\u003e patch\u003cT\u003e(IReturn\u003cT\u003e request, {dynamic body, Map\u003cString, dynamic\u003e args});\n  Future\u003cMap\u003cString, dynamic\u003e\u003e patchToUrl(String path, dynamic body, {Map\u003cString, dynamic\u003e args});\n  Future\u003cT\u003e patchAs\u003cT\u003e(String path, dynamic body, {Map\u003cString, dynamic\u003e args, T responseAs});\n\n  Future\u003cList\u003cT\u003e\u003e sendAll\u003cT\u003e(Iterable\u003cIReturn\u003cT\u003e\u003e requests);\n  Future\u003cvoid\u003e sendAllOneWay\u003cT\u003e(Iterable\u003cIReturn\u003cT\u003e\u003e requests);\n\n  Future\u003cT\u003e send\u003cT\u003e(IReturn\u003cT\u003e request, {String method, Map\u003cString, dynamic\u003e args, T responseAs});\n}\n```\n\n#### Concrete-specific functionality\n\nIn addition to implementing the `IServiceClient` above, each Service Client includes additional concrete specific functionality allowing for finer-grained access to their underlying HTTP Clients, e.g. as the Request/Response filters have different Type signatures (dart:io's `HttpClientResponse` vs Browser's `Response`) they can't be declared in the shared `IServiceClient` interface, but thanks to Dart's type inference many of the extended concrete APIs are still source-compatible, e.g:\n\n```dart\nvar vmClient = JsonServiceClient.api(baseUrl)\n    ..responseFilter = (res) =\u003e print(res.headers[\"X-Args\"]);\n\nvar webClient = JsonWebClient.api(baseUrl)\n    ..responseFilter = (res) =\u003e print(res.headers[\"X-Args\"]);\n```\n\n#### Comprehensive Test Suite\n\nTo ensure a high quality implementation we've ported the [TypeScript @servicestack/client](https://github.com/ServiceStack/servicestack-client) test suite over to Dart which is itself a good resource for discovering [different supported features and flexible HTTP Request options](https://github.com/ServiceStack/servicestack-dart/tree/master/test) available. \n\n### HelloFlutter App\n\nTo showcase popular API Requests in action we've created a basic [HelloFlutter](https://github.com/ServiceStackApps/HelloFlutter) App that mimics functionality in the [HelloMobile](https://github.com/ServiceStackApps/HelloMobile) App used to provide working examples of the same ServiceStack Service Client features running in the different supported Mobile and Desktop platforms.\n\n[HelloFlutter](https://github.com/ServiceStackApps/HelloFlutter) was created in VS Code with the [DartCode extension](https://dartcode.org) using the [Flutter: New Project](https://flutter.io/get-started/test-drive/#vscode) action in VS Code's Command Palette.\n\nThis creates a basic Flutter App which you can run in your Android Device or Android Emulator where it's automatically picked and made visible in the **bottom right** of VS Code's status bar.\n\nThen to use `JsonServiceClient` add the `servicestack` dependency to your apps [pubspec.yaml](https://github.com/ServiceStackApps/HelloFlutter/blob/master/pubspec.yaml):\n\n```yaml\ndependencies:\n  servicestack: ^1.0.32\n```\n\nSaving `pubspec.yaml` automatically runs [flutter packages get](https://flutter.io/using-packages/) to install any new dependencies in your App. \n\nOur App will be making API calls to 2 different ServiceStack instances which we'll need to get typed DTOs for using the `x` command-line utility:\n\n    $ cd lib\n    $ x dart https://techstacks.io\n    $ x dart https://test.servicestack.net test\n\nWhich will save the DTOs for each endpoint in different files:\n\n    Saved to: dtos.dart\n    Saved to: test.dtos.dart\n\nIncidentally you can get the latest version for all Dart Service References by running `x dart` without arguments:\n\n    $ x dart\n\nWhich updates all Dart references in the current directory, including any customization options available in the header of each file:\n\n    Updated: test.dtos.dart\n    Updated: dtos.dart\n\nThis gives us everything we need to call Web Services in our Flutter App, by importing `package:servicestack/client.dart` containing `JsonServiceClient` as well as any generated DTOs.\n\nThen create new `JsonServiceClient` instances initialized with the `BaseUrl` for each of the remote endpoints we want to call:\n\n```dart\nimport 'package:servicestack/client.dart';\n\nimport 'test.dtos.dart';\nimport 'dtos.dart';\n\nconst TestBaseUrl = \"https://test.servicestack.net\";\nconst TechStacksBaseUrl = \"https://techstacks.io\";\n\nvar testClient = JsonServiceClient.api(TestBaseUrl);\nvar techstacksClient = JsonServiceClient.api(TechStacksBaseUrl);\n```\n\n### HelloFlutter UI\n\nFlutter works similarly to React and React Native where you need to return the entire UI layout for your Widget in its `Widget build(BuildContext context)` method, akin to React's `render()` method. For complete reference the app is contained in [lib/main.dart](https://github.com/ServiceStackApps/HelloFlutter/blob/master/lib/main.dart), but for clarity we'll just highlight the relevant parts in each section. \n\nOur widget requires some state to render its UI so our widget needs to inherit `StatefulWidget`. Stateful widgets require an additional supporting class for reasons [explained in this Thread](https://github.com/flutter/flutter/issues/8794):\n\n\u003e With a stateful widget, it's common to make closures whose life cycle are tied to the state's life cycle, which lasts through multiple widgets. With a stateless widget, it's common to make closures whose life cycle are tied to the widget's life cycle, which doesn't cause a problem.\n\nUltimately this results in following the same dual class pattern below where the `HelloFlutterState` defines the state it needs as instance fields, this state is preserved across Hot Module reloads which is how Dart can update a live running App despite the implementation of the class changing.\n\n```dart\nclass HelloFlutter extends StatefulWidget {\n  @override\n  State\u003cStatefulWidget\u003e createState() =\u003e HelloFlutterState();\n}\n\nclass HelloFlutterState extends State\u003cHelloFlutter\u003e {\n  //State for this widget\n  String result = \"\";\n  Uint8List imageBytes = Uint8List(0);\n\n  @override\n  Widget build(BuildContext context) {\n\n      //...\n      RaisedButton(\n        child: Text(\"Async\"),\n        onPressed: () async {\n          var r = await testClient.get(Hello(name: \"Async\"));\n          setState(() {\n            result = r.result;\n          });\n        },\n      ),\n\n      //...\n      result != null \u0026\u0026 result != \"\" \n          ? Text(result) \n          : Image.memory(imageBytes, width:500.0, height:170.0),\n  }\n}\n```\n\nHelloFlutter's UI consists of 6 buttons across the top of the screen and an area to display the results of each call in the Widget's body. Each of the example Requests will populate either the `result` String for standard JSON responses or `imageBytes` for the `HelloImage` Service returning binary data.\n\n#### Standard API Requests\n\nThe first **Async** example shows an example of the most popular API Request for calling ServiceStack Services, simply by sending a populated Request DTO that returns a populated Response DTO, in this case sending a `Hello` Request DTO that returns a `HelloResponse` DTO:\n\n```dart\nvar r = await testClient.get(Hello(name: \"Async\"));\nsetState(() {\n  result = r.result;\n});\n```\n\nTo update the UI any modified State needs to be done within the `setState((){ })` closure which triggers re-rendering of the Widget with the new state.\n\nThis results in displaying the contents of the `result` String in a `Text` widget that was returned by the remote `Hello` Service:\n\n![](https://raw.githubusercontent.com/ServiceStack/docs/master/docs/images/dart/flutter/helloflutter-01.png)\n\n\n#### Authenticated Requests\n\nThis example shows how to make Authenticated Requests where first the `JsonServiceClient` instance is authenticated by sending a `Authenticate` request with valid Username/Password credentials which is validated against the servers configured [CredentialsAuthProvider](https://docs.servicestack.net/authentication-and-authorization#auth-providers). If successful this will return [Session Cookies](https://docs.servicestack.net/sessions) containing a reference to the Authenticated UserSession stored on the server. The Cookies are automatically saved on the `JsonServiceClient` instance and re-sent on subsequent requests which is how it's able to make an Authenticated request to the [protected `HelloAuth` Service](https://github.com/ServiceStack/Test/blob/3cc559d8de79e1c70ff7f4327458040ca055dea3/src/Test/Test.ServiceInterface/TestAuthService.cs#L18-L19):\n\n```dart\nRaisedButton(\n  child: Text(\"Auth\"),\n  onPressed: () async {\n\n    var auth = await testClient.post(Authenticate(\n        provider: \"credentials\",\n        userName: \"test\",\n        password: \"test\"));\n\n    var r = await testClient.get(HelloAuth(name: \"Auth\"));\n\n    setState(() {\n      result = \"${r.result} your JWT is: ${auth.bearerToken}\";\n    });\n  },\n),\n```\n\nIf the Username and Password were valid it will display the result of the `HelloAuth` Service along with the encapsulated JWT Token returned in the initial `AuthenticateResponse` call. \n\n![](https://raw.githubusercontent.com/ServiceStack/docs/master/docs/images/dart/flutter/helloflutter-02.png)\n\nJWT's encapsulate a signed, stateless Authenticated UserSession which is able to Authenticate with remote Services that have an `JwtAuthProvider` registered with the same AES or RSA Key used to sign the JWT Token. As they enable [Authentication with stateless Services they're ideal for use in Microservices](https://docs.servicestack.net/jwt-authprovider#stateless-auth-microservices).\n\n#### JWT RefreshToken Requests\n\nThe JWT sample shows an example of authenticating via JWT, but instead of configuring the `JsonServiceClient` instance with the JWT BearerToken above (and what's needed to make JWT Authenticated Requests), it's only populating the [long-lived RefreshToken](https://docs.servicestack.net/jwt-authprovider#refresh-tokens) which the client automatically uses behind the scenes to fetch a new JWT Bearer Token from the remote ServiceStack endpoint, which if the User is still allowed to Sign In will populate the instance with a new JWT Bearer Token encapsulated with the latest UserSession.\n\n```dart\nRaisedButton(\n  child: Text(\"JWT\"),\n  onPressed: () async {\n    var auth = await testClient.post(Authenticate(\n        provider: \"credentials\",\n        userName: \"test\",\n        password: \"test\"));\n\n    var newClient = JsonServiceClient.api(TestBaseUrl)\n      ..refreshToken = auth.refreshToken;\n    \n    var r = await newClient.get(HelloAuth(name: \"JWT\"));\n\n    setState(() {\n      result = \"${r.result} your RefreshToken is: ${auth.refreshToken}\";\n    });\n  },\n),\n```\n\nThe RefreshToken is smaller than a JWT Bearer Token as it just contains a signed token with permission to fetch new JWT Tokens and not the actual UserSession contained in the JWT Bearer Token.\n\n![](https://raw.githubusercontent.com/ServiceStack/docs/master/docs/images/dart/flutter/helloflutter-03.png)\n\n#### AutoQuery Requests\n\n[AutoQuery](https://docs.servicestack.net/autoquery-rdbms) lets us effortlessly creating queryable high-performance RDBMS APIs with just a Request DTO class definition, e.g:\n\n```csharp\n[Route(\"/technology/search\")]\npublic class FindTechnologies : QueryDb\u003cTechnology\u003e\n{\n    public string Name { get; set; }\n    public string NameContains { get; set; }\n}\n```\n\nServiceStack takes care of creating the implementation for this Service from this definition which queries the `Technology` RDBMS table. \n\nAny properties added to the AutoQuery Request DTO will be generated in the Dart `FindTechnologies` Request DTO. However AutoQuery also lets you query any other property on the `Technology` table using any of the configured [Implicit Conventions](https://docs.servicestack.net/autoquery-rdbms#implicit-conventions). \n\nWe can include any additional arguments that are not explicitly defined on the Request DTO using the optional `args` parameter available in each `IServiceClient` API.\n\nThis examples calls 2 different AutoQuery Services, first to retrieve the **Flutter** `Technology` in https://techstacks.io to retrieve its `id` which it uses to query the latest `Announcement` or `Showcase` posted in the **Flutter** organization:\n\n```dart\nRaisedButton(\n  child: Text(\"Query\"),\n  onPressed: () async {\n    \n    var techs = await techstacksClient.get(FindTechnologies(), args: {\"slug\": \"flutter\"});\n    \n    var posts = await techstacksClient.get(QueryPosts(\n        anyTechnologyIds: [techs.results[0].id],\n        types: ['Announcement', 'Showcase'])\n      ..take = 1);\n\n    setState(() {\n      result = \"Latest Flutter Announcement:\\n“${posts.results[0].title}”\";\n    });\n  },\n),\n```\n\nThe 2nd Request calls the `QueryPosts` AutoQuery Service highlighting the Service Client's support for [sending complex type arguments on the QueryString](https://docs.servicestack.net/serialization-deserialization#passing-complex-objects-in-the-query-string) and an example of using Dart's method cascade operator to populate the `take` field in  the [inherited QueryBase class](https://docs.servicestack.net/autoquery-rdbms#iquery).\n\n![](https://raw.githubusercontent.com/ServiceStack/docs/master/docs/images/dart/flutter/helloflutter-04.png)\n\n#### Auto Batched Requests\n\nThe `sendAll` and `sendAllOneWay` APIs lets you use ServiceStack's [Auto Batched Requests](https://docs.servicestack.net/auto-batched-requests) feature to batch multiple Requests DTOs of the same Type in a single Request that returns all Responses in a single Response, e.g:\n\n```dart\nRaisedButton(\n  child: Text(\"Batch\"),\n  onPressed: () async {\n    \n    var requests = ['foo', 'bar', 'qux']\n        .map((name) =\u003e Hello(name: name));\n    \n    var responses = await testClient.sendAll(requests);\n\n    setState(() {\n      result = \"Batch Responses:\\n${responses.map((r) =\u003e r.result).join('\\n')}\";\n    });\n  },\n),\n```\n\n![](https://raw.githubusercontent.com/ServiceStack/docs/master/docs/images/dart/flutter/helloflutter-05.png)\n\n#### Generating Unknown Types\n\nThis is one area where we hit limitations of not being able to use Reflection in Dart which requires generating factories ahead-of-time for each type we need to create instances of at runtime. This is typically inferred by inspecting all Types referenced in each DTO, but as Auto Batched Requests lets you combine multiple requests for every Service, in the interest for reducing the amount of code-generation needed ServiceStack doesn't generate an explicit Service Contract for the Batched version of each API. \n\nInstead you'll need to specify missing types needed, the easiest solution to do this is to create a Dummy Service containing properties of any missing Types needed, in this case we need to generate a factory for the `List\u003cHelloResponse\u003e` used to return the batched `HelloResponse` DTOs in:\n\n```csharp\npublic class DummyTypes\n{\n    public List\u003cHelloResponse\u003e HelloResponses { get; set; }\n}\n\npublic class DummyTypesService : Service\n{\n    public object Any(DummyTypes request) =\u003e request;\n}\n```\n\n#### Binary Requests\n\nMost API Requests typically involve sending a populated Request DTO that returns a Typed Response DTO although ServiceStack Services can also [return raw data](https://docs.servicestack.net/service-return-types) like `String`, `byte[]` and `Stream` responses which the `JsonServiceClient` also seamlessly supports where instead of returning a Typed DTO it returns the raw HTTP Body as a `String` for Request DTOs implementing `IReturn\u003cString\u003e` or an `Uint8List` for any binary responses (e.g. Services implementing `IReturn\u003cbyte[]\u003e` or `IReturn\u003cStream\u003e`).\n\nThis example calls the [`HelloImage` Service](https://github.com/ServiceStack/Test/blob/90678a1d57ac63daaafea7322e0a4f542a93488f/src/Test/Test.ServiceInterface/ImageService.cs#L137) which dynamically creates and returns an image based on the different properties on the incoming `HelloImage` Request DTO. As it implements `IReturn\u003cbyte[]\u003e` the `JsonServiceClient` returns the binary contents of the HTTP Response in a `Uint8List` - the preferred type for bytes in Dart.\n\n```dart\nRaisedButton(\n  child: Text(\"Image\"),\n  onPressed: () async {\n\n    Uint8List bytes = await testClient.get(HelloImage(\n        name: \"Flutter\",\n        fontFamily: \"Roboto\",\n        background: \"#0091EA\",\n        width: 500,\n        height: 170));\n\n    setState(() {\n      result = \"\";\n      imageBytes = bytes;\n    });\n\n  },\n),\n\n//...\nresult != null \u0026\u0026 result != \"\" \n    ? Text(result) \n    : Image.memory(imageBytes, width:500.0, height:170.0),\n```\n\nTo display the image we assign the response to the `imageBytes` field within the stateful widget's `setState()` which triggers a re-render of the UI containing the generated Image displayed using the [Image widget](https://docs.flutter.io/flutter/widgets/Image-class.html):\n\n![](https://raw.githubusercontent.com/ServiceStack/docs/master/docs/images/dart/flutter/helloflutter-06.png)\n\n### Angular Dart\n\nThe [HelloAngularDart](https://github.com/ServiceStackApps/HelloAngularDart) project demonstrates the same functionality in an AngularDart Web App running inside a Web Browser.\n\nThe only difference is having to import `servicestack/web_client.dart` containing the `JsonWebClient`:\n\n```dart\nimport 'package:servicestack/web_client.dart';\n```\n\nand changing the clients to use the `JsonWebClient` instead, e.g:\n\n```dart\nvar testClient = JsonWebClient.api(TestBaseUrl);\nvar techstacksClient = JsonWebClient.api(TechStacksBaseUrl);\n```\n\nBut otherwise the actual client source code for all of the Typed API requests remains exactly the same. \n\nThe `HelloAngularDart` App is contained within the [hello_world](https://github.com/ServiceStackApps/HelloAngularDart/tree/master/lib/src/hello_world) component with all Dart logic in:\n\n#### [hello_world.dart](https://github.com/ServiceStackApps/HelloAngularDart/blob/master/lib/src/hello_world/hello_world.dart)\n\n```dart\nimport 'dart:typed_data';\nimport 'dart:convert';\n\nimport 'package:angular/angular.dart';\nimport 'package:servicestack/web_client.dart';\n\nimport '../dtos/test.dtos.dart';\nimport '../dtos/dtos.dart';\n\n@Component(\n  selector: 'hello-world',\n  styleUrls: const ['hello_world.css'],\n  templateUrl: 'hello_world.html',\n)\nclass HelloWorldComponent {\n  var result = \"\";\n  var imageSrc = \"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\"; // 1x1 pixel\n  static const TestBaseUrl = \"https://test.servicestack.net\";\n  static const TechStacksBaseUrl = \"https://techstacks.io\";\n  var testClient = JsonWebClient.api(TestBaseUrl);\n  var techstacksClient = JsonWebClient.api(TechStacksBaseUrl);\n\n  doAsync() async {\n    var r = await testClient.get(Hello(name: \"Async\"));\n    result = r.result;\n  }\n\n  doAuth() async {\n    var auth = await testClient.post(Authenticate(\n        provider: \"credentials\", userName: \"test\", password: \"test\"));\n    var r = await testClient.get(HelloAuth(name: \"Auth\"));\n    result = \"${r.result} your JWT is: ${auth.bearerToken}\";\n  }\n\n  doJWT() async {\n    var auth = await testClient.post(Authenticate(\n        provider: \"credentials\", userName: \"test\", password: \"test\"));\n\n    var newClient = JsonWebClient.api(TestBaseUrl)\n      ..refreshToken = auth.refreshToken;\n    var r = await newClient.get(HelloAuth(name: \"JWT\"));\n    result = \"${r.result} your RefreshToken is: ${auth.refreshToken}\";\n  }\n\n  doQuery() async {\n    var techs = await techstacksClient\n        .get(FindTechnologies(), args: {\"slug\": \"flutter\"});\n    var posts = await techstacksClient.get(QueryPosts(\n        anyTechnologyIds: [techs.results[0].id],\n        types: ['Announcement', 'Showcase'])\n      ..take = 1);\n    result = \"Latest Flutter Announcement:\\n“${posts.results[0].title}”\";\n  }\n\n  doBatch() async {\n    var requests = ['foo', 'bar', 'qux'].map((name) =\u003e Hello(name: name));\n    var responses = await testClient.sendAll(requests);\n    result = \"Batch Responses:\\n${responses.map((r) =\u003e r.result).join('\\n')}\";\n  }\n\n  doImage() async {\n    Uint8List bytes = await testClient.get(HelloImage(\n        name: \"Flutter\",\n        fontFamily: \"Roboto\",\n        background: \"#0091EA\",\n        width: 500,\n        height: 170));\n\n    result = \"\";\n    imageSrc = \"data:image/png;base64,\" + base64.encode(bytes);\n  }\n}\n```\n\n#### [hello_world.html](https://github.com/ServiceStackApps/HelloAngularDart/blob/master/lib/src/hello_world/hello_world.html)\n\nWhich uses this template markup to render its UI:\n\n```html\n\u003cdiv\u003e\n    \u003cbutton (click)=\"doAsync()\"\u003eAsync\u003c/button\u003e\n    \u003cbutton (click)=\"doAuth()\"\u003eAuth\u003c/button\u003e\n    \u003cbutton (click)=\"doJWT()\"\u003eJWT\u003c/button\u003e\n    \u003cbutton (click)=\"doQuery()\"\u003eQuery\u003c/button\u003e\n    \u003cbutton (click)=\"doBatch()\"\u003eBatch\u003c/button\u003e\n    \u003cbutton (click)=\"doImage()\"\u003eImage\u003c/button\u003e\n\u003c/div\u003e\n\n\u003cdiv id=\"result\"\u003e{{result}}\u003c/div\u003e\n\n\u003cimg src=\"{{imageSrc}}\"\u003e\n```\n\nWhere it runs a functionally equivalent App in a browser:\n\n![](https://raw.githubusercontent.com/ServiceStack/docs/master/docs/images/dart/angulardart/helloangulardart-01.png)\n\n## DTO Customization Options \n\nIn most cases you'll just use the generated Dart DTOs as-is, however you can further customize how\nthe DTOs are generated by overriding the default options.\n\nThe header in the generated DTOs show the different options Dart native types support with their \ndefaults. Default values are shown with the comment prefix of `//`. To override a value, remove the `//` \nand specify the value to the right of the `:`. Any uncommented value will be sent to the server to override \nany server defaults.\n\nThe DTO comments allows for customizations for how DTOs are generated. The default options that were used \nto generate the DTOs are repeated in the header comments of the generated DTOs, options that are preceded \nby a Dart comment `//` are defaults from the server, any uncommented value will be sent to the server \nto override any server defaults.\n\n```dart\n/* Options:\nDate: 2018-05-01 08:09:24\nVersion: 5.10\nTip: To override a DTO option, remove \"//\" prefix before updating\nBaseUrl: https://techstacks.io\n\n//GlobalNamespace: \n//AddServiceStackTypes: True\n//AddResponseStatus: False\n//AddImplicitVersion: \n//AddDescriptionAsComments: True\n//IncludeTypes: \n//ExcludeTypes: \n//DefaultImports: package:servicestack/client.dart\n*/\n```\n\nWe'll go through and cover each of the above options to see how they affect the generated DTOs:\n\n### Change Default Server Configuration\n\nThe above defaults are also overridable on the ServiceStack Server by modifying the default config on the \n`NativeTypesFeature` Plugin, e.g:\n\n```csharp\n//Server example in CSharp\nvar nativeTypes = this.GetPlugin\u003cNativeTypesFeature\u003e();\nnativeTypes.MetadataTypesConfig.GlobalNamespace = \"dtos\";\n...\n```\n\nWe'll go through and cover each of the above options to see how they affect the generated DTOs:\n\n### GlobalNamespace\n\nSpecify a library for the generated Dart DTOs:\n\n```dart\nlibrary dtos;\n```\n\n### AddResponseStatus\n\nAutomatically add a `ResponseStatus` property on all Response DTOs, regardless if it wasn't already defined:\n\n```dart\nclass  GetAnswers implements IReturn\u003cGetAnswersResponse\u003e\n{\n    ...\n    ResponseStatus responseStatus;\n}\n```\n\n### AddImplicitVersion\n\nLets you specify the Version number to be automatically populated in all Request DTOs sent from the client: \n\n```dart\nclass GetAnswers implements IReturn\u003cGetAnswersResponse\u003e\n{\n    int version = 1;\n    ...\n}\n```\n\nThis lets you know what Version of the Service Contract that existing clients are using making it easy \nto implement ServiceStack's [recommended versioning strategy](http://stackoverflow.com/a/12413091/85785). \n\n### IncludeTypes\n\nIs used as a Whitelist to specify only the types you would like to have code-generated:\n\n```\n/* Options:\nIncludeTypes: GetTechnology,GetTechnologyResponse\n```\n\nWill only generate `GetTechnology` and `GetTechnologyResponse` DTOs:\n\n```csharp\nclass class GetTechnology { ... }\nclass class GetTechnologyResponse { ... }\n```\n\n#### Include Request DTO and its dependent types\n\nYou can include a Request DTO and all its dependent types with a `.*` suffix on the Request DTO, e.g:\n\n```\n/* Options:\nIncludeTypes: GetTechnology.*\n```\n\nWhich will include the `GetTechnology` Request DTO, the `GetTechnologyResponse` Response DTO and all Types that they both reference.\n\n#### Include All Types within a C# namespace\n\nIf your DTOs are grouped into different namespaces they can be all included using the `/*` suffix, e.g:\n\n```\n/* Options:\nIncludeTypes: MyApp.ServiceModel.Admin/*\n```\n\nThis will include all DTOs within the `MyApp.ServiceModel.Admin` C# namespace. \n\n### ExcludeTypes\nIs used as a Blacklist to specify which types you would like excluded from being generated:\n\n```\n/* Options:\nExcludeTypes: GetTechnology,GetTechnologyResponse\n```\n\nWill exclude `GetTechnology` and `GetTechnologyResponse` DTOs from being generated.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fservicestack%2Fservicestack-dart","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fservicestack%2Fservicestack-dart","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fservicestack%2Fservicestack-dart/lists"}