servicestack_web 0.0.1 copy "servicestack_web: ^0.0.1" to clipboard
servicestack_web: ^0.0.1 copied to clipboard

outdated

ServiceStack convenience utils for developing Dart Web and AngularDart apps. Integrates with ServiceStack's Server features including ServiceClient, Error Handling and Validation

Dart Banner

servicestack_web #

ServiceStack Dart ServiceClient for Dart Web and AngularDart projects.

ServiceStack's Add ServiceStack Reference feature allows clients to generate Native Types from a simple @servicestack/cli command-line utility - providing a simple way to give clients typed access to your ServiceStack Services.

Dart ServiceStack Reference #

Dart 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 where it doesn't requiring any additional tooling, transformers or build steps.

Due to the lack of reflection and Mirror support, consuming JSON APIs can be quite cumbersome in Flutter. But we've been able to achieve the same productive development experience available in all supported languages where you can use the generated Dart DTOs from any remote v5.1+ ServiceStack endpoint with ServiceStack's Smart generic JsonServiceClient available in the servicestack Dart package, to enable an end-to-end Typed API for calling Services by sending and receiving native DTOs.

Example Usage #

You can use the same @servicestack/cli simple command-line utility to easily Add and Update ServiceStack References for all supported languages:

$ npm install -g @servicestack/cli

This makes the dart-ref script globally available in your PATH which you can execute with the URL of the remote ServiceStack Instance you want to generated DTOs for, e.g:

$ dart-ref https://www.techstacks.io

This will generate Dart DTOs for the entire TechStacks API:

Saved to: techstacks.dtos.dart

If no name is specified in the 2nd argument, it's inferred from the URL, in this case it uses techstacks.

To make API calls we need to use the JsonWebClient, installed by adding the servicestack and servicestack_web packages to our Dart projects pubspec.yaml:

dependencies:
  servicestack: ^1.0.4
  servicestack_web: ^0.0.1

Saving pubspec.yaml in VS Code with the Dart Code Extension automatically calls pub get to add any new dependencies to your project.

We now have everything we need to be able to make typed API requests to any of TechStacks APIs with a shared JsonWebClient instance populated with the base URL of the remote endpoint, e.g:

import 'package:servicestack_web/client.dart';

import 'techstacks.dtos.dart';

var client = new JsonWebClient("https://www.techstacks.io");

main() async {
  var response = await client.get(new GetTechnology(slug: "flutter"));
  print("${response.technology.name}: ${response.technology.vendorUrl}");
}

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.

For any non-browser projects, e.g. Flutter, Dart VM, Server or command-line tests you would instead use the JsonServiceClient from the primary servicestack Dart package, e.g:

import 'package:servicestack/client.dart';

var client = new JsonServiceClient("https://www.techstacks.io");

JsonWebClient #

The servicestack_web Dart package JsonWebClient performs HTTP Requests using dart:html BrowserClient 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.

AngularDart or Dart Web Apps can use JsonWebClient by importing package:servicestack_web/client.dart, e.g:

import 'package:servicestack_web/client.dart';

var client = new JsonWebClient("https://www.techstacks.io");

Concrete-specific functionality

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:

var vmClient = new JsonServiceClient(baseUrl)
    ..responseFilter = (res) => print(res.headers["X-Args"]);

var webClient = new JsonWebClient(baseUrl)
    ..responseFilter = (res) => print(res.headers["X-Args"]);

Angular Dart #

The HelloAngularDart project demonstrates the same functionality in an AngularDart Web App running inside a Web Browser.

The only difference is having to also import web.dart containing the JsonWebClient:

import 'package:servicestack_web/client.dart';

and changing the clients to use the JsonWebClient instead, e.g:

var testClient = new JsonWebClient(TestBaseUrl);
var techstacksClient = new JsonWebClient(TechStacksBaseUrl);

But otherwise the actual client source code for all of the Typed API requests remains exactly the same.

The HelloAngularDart App is contained within the hello_world component with all Dart logic in:

hello_world.dart

import 'dart:typed_data';
import 'dart:convert';

import 'package:angular/angular.dart';
import 'package:servicestack/client.dart';
import 'package:servicestack_web/client.dart';

import '../dtos/test.dtos.dart';
import '../dtos/techstacks.dtos.dart';

@Component(
  selector: 'hello-world',
  styleUrls: const ['hello_world.css'],
  templateUrl: 'hello_world.html',
)
class HelloWorldComponent {
  var result = "";
  var imageSrc = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="; // 1x1 pixel
  static const TestBaseUrl = "http://test.servicestack.net";
  static const TechStacksBaseUrl = "https://www.techstacks.io";
  var testClient = new JsonWebClient(TestBaseUrl);
  var techstacksClient = new JsonWebClient(TechStacksBaseUrl);

  doAsync() async {
    var r = await testClient.get(new Hello(name: "Async"));
    result = r.result;
  }

  doAuth() async {
    var auth = await testClient.post(new Authenticate(
        provider: "credentials", userName: "test", password: "test"));
    var r = await testClient.get(new HelloAuth(name: "Auth"));
    result = "${r.result} your JWT is: ${auth.bearerToken}";
  }

  doJWT() async {
    var auth = await testClient.post(new Authenticate(
        provider: "credentials", userName: "test", password: "test"));

    var newClient = new JsonWebClient(TestBaseUrl)
      ..refreshToken = auth.refreshToken;
    var r = await newClient.get(new HelloAuth(name: "JWT"));
    result = "${r.result} your RefreshToken is: ${auth.refreshToken}";
  }

  doQuery() async {
    var techs = await techstacksClient
        .get(new FindTechnologies(), args: {"slug": "flutter"});
    var posts = await techstacksClient.get(new QueryPosts(
        anyTechnologyIds: [techs.results[0].id],
        types: ['Announcement', 'Showcase'])
      ..take = 1);
    result = "Latest Flutter Announcement:\n“${posts.results[0].title}”";
  }

  doBatch() async {
    var requests = ['foo', 'bar', 'qux'].map((name) => new Hello(name: name));
    var responses = await testClient.sendAll(requests);
    result = "Batch Responses:\n${responses.map((r) => r.result).join('\n')}";
  }

  doImage() async {
    Uint8List bytes = await testClient.get(new HelloImage(
        name: "Flutter",
        fontFamily: "Roboto",
        background: "#0091EA",
        width: 500,
        height: 170));

    result = "";
    imageSrc = "data:image/png;base64," + base64.encode(bytes);
  }
}

hello_world.html

Which uses this template markup to render its UI:

<div>
    <button (click)="doAsync()">Async</button>
    <button (click)="doAuth()">Auth</button>
    <button (click)="doJWT()">JWT</button>
    <button (click)="doQuery()">Query</button>
    <button (click)="doBatch()">Batch</button>
    <button (click)="doImage()">Image</button>
</div>

<div id="result">{{result}}</div>

<img src="{{imageSrc}}">

Where it runs a functionally equivalent App in a browser:

DTO Customization Options #

Please see docs on Dart DTO Customization Options for the information of the available customization options to change how Dart's Typed DTOs are generated.

0
likes
0
pub points
0%
popularity

Publisher

unverified uploader

ServiceStack convenience utils for developing Dart Web and AngularDart apps. Integrates with ServiceStack's Server features including ServiceClient, Error Handling and Validation

Repository (GitHub)
View/report issues

License

unknown (LICENSE)

Dependencies

http, servicestack

More

Packages that depend on servicestack_web