Skip to content

Commit a22c38b

Browse files
committed
Update docs to include JsonWebClient in web_client.dart
1 parent be3b201 commit a22c38b

File tree

1 file changed

+146
-2
lines changed

1 file changed

+146
-2
lines changed

README.md

Lines changed: 146 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ To make API calls we need to use the `JsonServiceClient`, installed by adding th
2929

3030
```yaml
3131
dependencies:
32-
servicestack: ^1.0.4
32+
servicestack: ^1.0.5
3333
```
3434
3535
Saving `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.
@@ -51,6 +51,30 @@ main() async {
5151

5252
Like 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.
5353

54+
### JsonWebClient
55+
56+
For browser projects you would instead use the `JsonWebClient` from `web_client.dart`, e.g:
57+
58+
```dart
59+
import 'package:servicestack/web_client.dart';
60+
61+
var client = new JsonWebClient("https://www.techstacks.io");
62+
```
63+
64+
The `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.
65+
66+
#### Concrete-specific functionality
67+
68+
In 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:
69+
70+
```dart
71+
var vmClient = new JsonServiceClient(baseUrl)
72+
..responseFilter = (res) => print(res.headers["X-Args"]);
73+
74+
var webClient = new JsonWebClient(baseUrl)
75+
..responseFilter = (res) => print(res.headers["X-Args"]);
76+
```
77+
5478
### Rich Generated Models
5579

5680
Thanks 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.
@@ -183,7 +207,7 @@ Then to use `JsonServiceClient` add the `servicestack` dependency to your apps [
183207

184208
```yaml
185209
dependencies:
186-
servicestack: ^1.0.4
210+
servicestack: ^1.0.5
187211
```
188212

189213
Saving `pubspec.yaml` automatically runs [flutter packages get](https://flutter.io/using-packages/) to install any new dependencies in your App.
@@ -467,6 +491,126 @@ To display the image we assign the response to the `imageBytes` field within the
467491

468492
![](https://raw.githubusercontent.com/ServiceStack/docs/master/docs/images/dart/flutter/helloflutter-06.png)
469493

494+
### Angular Dart
495+
496+
The [HelloAngularDart](https://github.com/ServiceStackApps/HelloAngularDart) project demonstrates the same functionality in an AngularDart Web App running inside a Web Browser.
497+
498+
The only difference is having to import `servicestack/web_client.dart` containing the `JsonWebClient`:
499+
500+
```dart
501+
import 'package:servicestack/web_client.dart';
502+
```
503+
504+
and changing the clients to use the `JsonWebClient` instead, e.g:
505+
506+
```dart
507+
var testClient = new JsonWebClient(TestBaseUrl);
508+
var techstacksClient = new JsonWebClient(TechStacksBaseUrl);
509+
```
510+
511+
But otherwise the actual client source code for all of the Typed API requests remains exactly the same.
512+
513+
The `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:
514+
515+
#### [hello_world.dart](https://github.com/ServiceStackApps/HelloAngularDart/blob/master/lib/src/hello_world/hello_world.dart)
516+
517+
```dart
518+
import 'dart:typed_data';
519+
import 'dart:convert';
520+
521+
import 'package:angular/angular.dart';
522+
import 'package:servicestack/web_client.dart';
523+
524+
import '../dtos/test.dtos.dart';
525+
import '../dtos/techstacks.dtos.dart';
526+
527+
@Component(
528+
selector: 'hello-world',
529+
styleUrls: const ['hello_world.css'],
530+
templateUrl: 'hello_world.html',
531+
)
532+
class HelloWorldComponent {
533+
var result = "";
534+
var imageSrc = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; // 1x1 pixel
535+
static const TestBaseUrl = "http://test.servicestack.net";
536+
static const TechStacksBaseUrl = "https://www.techstacks.io";
537+
var testClient = new JsonWebClient(TestBaseUrl);
538+
var techstacksClient = new JsonWebClient(TechStacksBaseUrl);
539+
540+
doAsync() async {
541+
var r = await testClient.get(new Hello(name: "Async"));
542+
result = r.result;
543+
}
544+
545+
doAuth() async {
546+
var auth = await testClient.post(new Authenticate(
547+
provider: "credentials", userName: "test", password: "test"));
548+
var r = await testClient.get(new HelloAuth(name: "Auth"));
549+
result = "${r.result} your JWT is: ${auth.bearerToken}";
550+
}
551+
552+
doJWT() async {
553+
var auth = await testClient.post(new Authenticate(
554+
provider: "credentials", userName: "test", password: "test"));
555+
556+
var newClient = new JsonWebClient(TestBaseUrl)
557+
..refreshToken = auth.refreshToken;
558+
var r = await newClient.get(new HelloAuth(name: "JWT"));
559+
result = "${r.result} your RefreshToken is: ${auth.refreshToken}";
560+
}
561+
562+
doQuery() async {
563+
var techs = await techstacksClient
564+
.get(new FindTechnologies(), args: {"slug": "flutter"});
565+
var posts = await techstacksClient.get(new QueryPosts(
566+
anyTechnologyIds: [techs.results[0].id],
567+
types: ['Announcement', 'Showcase'])
568+
..take = 1);
569+
result = "Latest Flutter Announcement:\n“${posts.results[0].title}”";
570+
}
571+
572+
doBatch() async {
573+
var requests = ['foo', 'bar', 'qux'].map((name) => new Hello(name: name));
574+
var responses = await testClient.sendAll(requests);
575+
result = "Batch Responses:\n${responses.map((r) => r.result).join('\n')}";
576+
}
577+
578+
doImage() async {
579+
Uint8List bytes = await testClient.get(new HelloImage(
580+
name: "Flutter",
581+
fontFamily: "Roboto",
582+
background: "#0091EA",
583+
width: 500,
584+
height: 170));
585+
586+
result = "";
587+
imageSrc = "data:image/png;base64," + base64.encode(bytes);
588+
}
589+
}
590+
```
591+
592+
#### [hello_world.html](https://github.com/ServiceStackApps/HelloAngularDart/blob/master/lib/src/hello_world/hello_world.html)
593+
594+
Which uses this template markup to render its UI:
595+
596+
```html
597+
<div>
598+
<button (click)="doAsync()">Async</button>
599+
<button (click)="doAuth()">Auth</button>
600+
<button (click)="doJWT()">JWT</button>
601+
<button (click)="doQuery()">Query</button>
602+
<button (click)="doBatch()">Batch</button>
603+
<button (click)="doImage()">Image</button>
604+
</div>
605+
606+
<div id="result">{{result}}</div>
607+
608+
<img src="{{imageSrc}}">
609+
```
610+
611+
Where it runs a functionally equivalent App in a browser:
612+
613+
![](https://raw.githubusercontent.com/ServiceStack/docs/master/docs/images/dart/angulardart/helloangulardart-01.png)
470614

471615
## DTO Customization Options
472616

0 commit comments

Comments
 (0)