ServiceStack v4.5.6

Hope everyone enjoyed their X-mas holiday break and are re-energized for a productive 2017!

We have another wide exciting release with new features and improvements added throughout ServiceStack starting with new and simplified Single Page App templates, Swift 3 support, enhanced Swift and TypeScript clients, .NET Core and .NET 4.5 and performance improvements, .NET Core MySql, SQL Server Memory Optimized Tables and lots more.

New Angular2 Single Page App template!

We're happy to introduce a modern VS.NET SPA template for Angular 2 in the latest version of ServiceStackVS. The new Angular2 template closely follows the existing npm-based TypeScript / JSPM / Gulp technology stack solidified in our other SPA templates with the main difference being that it's based on the Material Design Lite theme:

Whereas all other Single Page App templates are based on Bootstrap. We adopted Material Design Lite as we anticipate it's the more natural and popular choice for Angular Apps given they're both actively developed by Google.

Modular Layout

The Angular2 template also takes advantage of Angular2's modular architecture with a physical structure optimal for small-to-medium sized projects where its modular layout is compartmentalized into multiple independent sub modules. Each sub module can then be further divided into "feature folders" encapsulating the components required to render each individual page so they're able to be maintained separately:

src/
    main.module.ts          - Register all Modules used in entire App
    app.ts                  - Container component for entire App
    dtos.ts                 - TypeScript Server DTOs
    shared/                 - Shared Components available to entire App
        header.ts
        footer.ts
    modules/                - All Sub Modules used to construct App
        app/                - Main App Module
            home/           - Feature Folders
                home.ts     - The Home Page Tab Contents
                hello.html  - Hello Sub Component HTML Layout
                hello.ts    - Hello Sub Component TypeScript
            products/
            technology/
            app.module.ts   - All Dependencies + Routes used in Module

TypeScript Client Integration

Like all SPA Templates, Angular2 includes deep integration with ServiceStack with a TypeScript Service client that's preconfigured to make end-to-end typed API calls out-of-the-box:

var client = new JsonServiceClient('/');

var req = new Hello();
req.name = newValue;
client.get(req).then(r => {
    this.result = r.result
});

The TypeScript DTOs can then be easily updated by right-clicking on dtos.ts to Update the TypeScript reference and generate the TypeScript DTOs for any new Services.

The new Angular2 template also benefits from the improvements added to all Single Page App templates in this release:

Simpler and Optimized Single Page App Templates

Our goal with our Single Page App VS.NET templates is to provide access to the best tooling and development experience whilst keeping complexity and required knowledge to an absolute minimum, as such we're constantly researching how we can simplify our SPA templates by using the least moving parts and picking technologies that work seamlessly together whilst offering maximum value for minimal complexity. As the best SPA tooling mandates an npm-based workflow this becomes a delicate balance of trade-offs as the number of 3rd party JS components, tools, transpilers, scripts and plugins required for building on a modern SPA JS framework can quickly explode - something that influences each aspect of our defaults and we actively fight hard against to avoid.

SPA Template improvements

In following with these goals we've made a number of improvements to the existing SPA Templates:

Upgraded to JSPM 0.17 beta

All templates have been upgraded to the latest JSPM 0.17 beta which after a year in development gives us access to JSPM's latest features like Static Builds with Rollup Optimization which we're now using for production deployments where your entire App is statically-linked into a single optimized app.js, eliminating the need for system.js at runtime and removing the packaging overhead from using modules.

Removed interim deps.tsx

The interim deps.tsx file used to minimize the number of requests required during development is no longer needed. We're now able to generate a cache of 3rd party npm dependencies using your App's main .js file and your dependencies listed in npm's package.json.

The cached dependencies are still generated in deps.lib.js but are now run on first install so it mostly becomes a transparent implementation detail although after adding new package dependencies you can run the 00-update-deps Gulp task to re-generate the local cache.

Simplified Typings

The typings dependency manager has been removed leaving one less typings.json that needs to be maintained. Templates now use TypeScript's new @types definitions directly from npm or when they exist, the definitions contained in each npm package that's referenced in devDependencies. The only exception being es2015 which now references TypeScript's built-in es2015 declarations instead.

Upgraded to latest Bootstrap v4

The React and Aurelia SPA Templates have been upgraded to use the just released Bootstrap v4 alpha-6.

Use camelCase by default

In following with JS naming conventions all SPA Templates are now configured to use camelCase for JSON Web Services and their resulting generated Server DTOs.

Enhanced TypeScript Support

The SPA Templates also benefit from our enhanced TypeScript support with improvements to both the generated TypeScript DTOs and the JsonServiceClient which now includes TypeScript Definitions published with the npm package.

Support for Basic Auth

Basic Auth support is now implemented in JsonServiceClient and follows the same API made available in the C# Service Clients where the userName/password properties can be set individually, e.g:

var client = new JsonServiceClient(baseUrl);
client.userName = user;
client.password = pass;

client.get(new SecureRequest())
    .then(r => ...);

Or use client.setCredentials() to have them set both together.

Raw Data Responses

The JsonServiceClient also supports Raw Data responses like string and byte[] which also get a Typed API once declared on Request DTOs using the IReturn<T> marker:

public class ReturnString : IReturn<string> {}
public class ReturnBytes : IReturn<byte[]> {}

Which can then be accessed as normal, with their Response typed to a JavaScript string or Uint8Array for raw byte[] responses:

client.get(new ReturnString())
    .then(str => ...);  //= str:string

client.get(new ReturnBytes())
    .then(data => ...); //= data:Uint8Array

Swift 3

Swift Add ServiceStack Reference has been upgraded to Swift 3 which is now available from Xcode 8 and later.

Upgraded Swift 3 JsonServiceClient

The Swift JsonServiceClient implementation was overhauled and upgraded to use the latest Swift 3 PromiseKit implementation. The earlier Swift 2 compiler bugs preventing AutoQuery Services from working have now been resolved.

Unfortunately Swift still has a limitation requiring that the sub class of a generic class must also be a generic class which results in your AutoQuery Services (and any other Request DTOs inheriting from a generic class) needing to unnecessarily specify a generic Type arg when creating new instances, e.g:

let request = FindTechnologies<Technology>()
client.getAsync(request)
    .then { r -> QueryResponse<Technology> in
        //...
        return r
    }

swiftref OSX command-line utility

In response to XcodeGhost, Apple has killed support for plugins in Xcode 8 disabling all existing 3rd party plugins from working, and along with it our Integration with Xcode built into ServiceStack Xcode Plugin. As of now the only workaround to get plugins in Xcode 8 working again is to unsign and overwrite the Xcode binary.

Whilst Apple are positioning Xcode extensions as an alternative to Xcode plugins they're extremely weak in comparison as they don't allow basic things like adding new files to a project - limiting their usefulness.

To enable the best development experience we can without using an Xcode plugin we've developed the swiftref OSX command-line utility to provide a simple command-line UX to Add and Update Swift ServiceStack References.

Install swiftref

The easiest way to install swiftref is to download the pre-built OSX binary into your /usr/local/bin so it's available in your $PATH:

sudo curl https://raw.githubusercontent.com/ServiceStack/swiftref/master/dist/swiftref > /usr/local/bin/swiftref
sudo chmod +x /usr/local/bin/swiftref

After which can be used from within a Terminal window at your Xcode project folder.

Add a new ServiceStack Reference:

To Add a new ServiceStack Reference, call swiftref with the Base URL to a remote ServiceStack instance:

swiftref {BaseUrl}
swiftref {BaseUrl} {FileName}

Where if no FileName is provided, it's inferred from the host name of the remote URL, e.g:

swiftref https://techstacks.io

Downloads the Typed Swift DTOs for techstacks.io and saves them to techstacks.dtos.swift.

Alternatively you can have it saved to a different FileName with:

swiftref https://techstacks.io TechStacks

Which instead saves the DTOs to TechStacks.dtos.swift.

swiftref also downloads ServiceStack's Swift Client and saves it to JsonServiceClient.swift which together with the Server DTOs contains all the dependencies required to consume Typed Web Services in Swift.

Update an existing ServiceStack Reference:

To Update an existing ServiceStack Reference, call swiftref with the Filename:

swiftref {FileName.dtos.swift}

As an example, you can Update the Server DTOs added in the previous command with:

swiftref TechStacks.dtos.swift

Which also includes any Customization Options that were manually added.

All Swift Example Apps upgraded to Swift 3

Our existing Swift Example Apps have all been upgraded to use ServiceStack's new Swift 3 Support:

The latest TechStacks iPhone/iPad App and AutoQuery Viewer for iPad are also available to download on the App Store.

101 Swift LINQ Samples

A great resource for learning Swift from a C# background is the 101 LINQ Samples in Swift 3 which shows the equivalent Swift 3 code alongside C# for each of MSDN's 101 LINQ Examples.

Swift Package Manager Apps

In its quest to become a popular mainstream language, Swift now includes a built-in Package Manager to simplify the maintenance, distribution and building of Swift code. Swift Package Manager can be used to build native statically-linked modules or Console Apps but currently has no support for iOS, watchOS, or tvOS platforms.

Nevertheless it's simple console and text-based programming model provides a great way to quickly develop prototypes or Console-based Swift Apps like swiftref using your favorite text editor. To support this environment we've packaged ServiceStack's Swift Service clients into a ServiceStackClient package so it can be easily referenced in Swift PM projects.

Swift TechStacks Console App

Together with Swift Add ServiceStack Reference we now have a productive development workflow for building statically-linked native executables that consume Typed ServiceStack Services as seen in the new step-by-step guide below showing how to create a simple Swift TechStacks Console App.

First we have to reference the ServiceStackClient dependency in a plain-text Package.swift manifest file:

import PackageDescription

let package = Package(
    name: "TechStacks Console App",
    dependencies: [
        .Package(url: "https://github.com/ServiceStack/SwiftClient", majorVersion: 1)
    ]
)

Then create a Folder under /Sources to store the App source code:

mkdir -p Sources/App && cd Sources/App

Now download the Typed DTOs from the remote ServiceStack Service you want to access, e.g:

curl https://techstacks.io/types/swift?DefaultImports=Foundation,ServiceStackClient > TechStacks.dtos.swift

The above url includes a modified import in the generated DTOs by appending the ?DefaultImports=Foundation,ServiceStackClient query string to the Swift Types endpoint so it references the Service Client from ServiceStackClient package.

Now we have everything we need to make typed end-to-end API calls to TechStacks Services, all that's missing is writing the App that consumes them, which is added in main.swift:

import ServiceStackClient;

let client = JsonServiceClient(baseUrl:"https://techstacks.io")

let request = GetTechnology()
request.slug = "ServiceStack"

let response = try client.get(request)

print(response.technologyStacks[0].toJson());

This gives us a working App that can be built with:

swift build

Which instructs Swift PM to download and install any dependencies listed in Package.swift that it builds and links with your App in /Sources/App, the result is a statically-linked executable that can be run directly from the .build directory:

.build/debug/App

Where executing the App downloads Technology Stacks using ServiceStack, serializes the 1st Result to JSON, then prints the JSON output to the Console.

Service Fabric Example

Another Example project developed during this release is Hello ServiceFabric to show a Hello World example of running a ServiceStack Self Hosted Service inside Microsoft's Service Fabric platform.

Service Fabric is a distributed systems platform that enables wrapping self-hosted Services inside a managed package, allowing them to be treated like Containers where they can be scaled on a cluster and managed independently using Service Fabric's orchestration tooling.

App Clusters for Service Fabric can be created anywhere

You can create clusters for Service Fabric in many environments, including Azure or on premises, on Windows Server, or on Linux. In addition, the development environment in the SDK is identical to the production environment, and no emulators are involved. For more information on creating clusters on-premises, read creating a cluster on Windows Server or Linux or for Azure creating a cluster via the Azure portal.

Changes from Service Fabric Application VS.NET template

The main difference of this project from the default Service Fabric Application VS.NET Template is the SelfHostCommunicationListener.cs adapter class which implements Service Fabric's ICommunicationListener interface for managing the life-cycle of a ServiceStack Self-Host Service.

When creating a new Service Fabric Self Hosted Service from a VS.NET template, you can copy:

Into your project then change your StatelessSelfHost to use this class configured with your ServiceStack AppHost, e.g:

protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
    var endpoints = Context.CodePackageActivationContext.GetEndpoints()
        .Where(endpoint => endpoint.Protocol==EndpointProtocol.Http || endpoint.Protocol==EndpointProtocol.Https)
        .Select(endpoint => endpoint.Name);

    return endpoints.Select(endpoint => new ServiceInstanceListener(
        serviceContext => new SelfHostCommunicationListener(
            new AppHost(), serviceContext, ServiceEventSource.Current, endpoint), endpoint));
}

Performance Improvements

Our first support for .NET Core was primarily focused on compatibility and deep integration with .NET Core's Pipeline, Modules and Conventions. In this release we focused on performance and memory usage which we kicked off by developing a benchmarking solution for automatically spinning up Azure VM's that we use to run benchmarking and load tests against.

We've decided to run Benchmarks against a Cloud VM to give some resemblance of real numbers you can get when running on a popular commodity server environment.

A simple JSON Service running our initial .NET Core support in v4.5.4 release yields:

Benchmark Requests/Sec Average StdDev StdDev/Average (%)
.NET Core 1.1 26179 74 0.28
mono 4.6.2 (nginx+hyperfasctcgi) 6428 84 1.30

Running on Standard_F4s azure instance (4 Core, 8GB RAM) using the following wrk benchmarking tool command:

wrk -c 256 -t 8 -d 30 http://benchmarking_url

Using 8 threads, keeping 256 concurrent HTTP Connections open, Running for 30s.

With the profiling and performance improvements added in this release, the same service now yields:

Benchmark Requests/Sec Average StdDev StdDev/Average (%)
.NET Core 1.1 37073 271 0.73
mono 4.6.2 (nginx+hyperfasctcgi) 6840 63 0.93

Which is over a 40% improvement for this benchmark since last release.

Running the same ServiceStack Service on the same VM also shows us that .NET Core is 5.4x faster than our recommended Mono, nginx + HyperFastCGI configuration for running ASP.NET Web Applications on Mono.

Upgraded to .NET Core 1.1

We're closely following .NET Core's progress and continue to upgrade ServiceStack libraries and their test suites to run on the latest stable .NET Core release which as of this release is .NET Core 1.1.

Client/Server Request Compression

Previously compression was limited to optimized cached Server Responses which are also supported by default in all Service Clients.

You can now also elect to compress HTTP Requests in any C#/.NET Service Clients by specifying the Compression Type you wish to use, e.g:

var client = new JsonServiceClient(baseUrl) {
    RequestCompressionType = CompressionTypes.GZip,
};

var client = new JsonHttpClient(baseUrl) {
    RequestCompressionType = CompressionTypes.Deflate,
};

var response = client.Post(new Request { ... });

Where sending any HTTP Request containing a Request Body (e.g. POST/PUT) will send a compressed Request body to the Server where it's now able to be transparently decompressed and deserialized into your Request DTO.

FileSystem Mapping

Custom FileSystem mappings can now be easily registered under a specific alias by overriding your AppHost's GetVirtualFileSources() and registering a custom FileSystemMapping, e.g:

public override List<IVirtualPathProvider> GetVirtualFileSources()
{
    var existingProviders = base.GetVirtualFileSources();
    existingProviders.Add(new FileSystemMapping(this, "img", "i:\\images"));
    existingProviders.Add(new FileSystemMapping(this, "docs", "d:\\documents"));
    return existingProviders;
}

This will let you access File System Resources under the custom /img and /doc routes, e.g:

  • http://host/img/the-image.jpg
  • http://host/docs/word.doc

SQL Server Features

Kevin Howard has continued enhancing the SQL Server Support in OrmLite with access to advanced SQL Server features including Memory-Optimized Tables where you can tell SQL Server to maintain specific tables in Memory using the [SqlServerMemoryOptimized] attribute, e.g:

[SqlServerMemoryOptimized(SqlServerDurability.SchemaOnly)]
public class SqlServerMemoryOptimizedCacheEntry : ICacheEntry
{
    [PrimaryKey]
    [StringLength(StringLengthAttribute.MaxText)]
    [SqlServerBucketCount(10000000)]
    public string Id { get; set; }
    [StringLength(StringLengthAttribute.MaxText)]
    public string Data { get; set; }
    public DateTime CreatedDate { get; set; }
    public DateTime? ExpiryDate { get; set; }
    public DateTime ModifiedDate { get; set; }
}

The [SqlServerBucketCount] attribute can be used to configure the bucket count for a hash index whilst the new [SqlServerCollate] attribute can be used to specify an SQL Server collation.

The new Memory Optimized support can be used to improve the performance of SQL Server OrmLiteCacheClient by configuring it to use the above In Memory Table Schema instead, e.g:

container.Register<ICacheClient>(c => 
    new OrmLiteCacheClient<SqlServerMemoryOptimizedCacheEntry>());

PostgreSQL Data Types

To make it a little nicer to be define custom PostgreSQL columns, we've added [PgSql*] specific attributes which will let you use a typed [PgSqlJson] instead of previously needing to use [CustomField("json")]. Other attributes available include:

public class MyPostgreSqlTable
{
    [PgSqlJson]
    public List<Poco> AsJson { get; set; }

    [PgSqlJsonB]
    public List<Poco> AsJsonB { get; set; }

    [PgSqlTextArray]
    public string[] AsTextArray { get; set; }

    [PgSqlIntArray]
    public int[] AsIntArray { get; set; }

    [PgSqlBigIntArray]
    public long[] AsLongArray { get; set; }
}

.NET Core support for MySql

You can now use OrmLite with MySQL in .NET Core using the new ServiceStack.OrmLite.MySql.Core NuGet package. As it's dependent on the MySql.Data 7.0.6-IR31 Pre-release NuGet package, it needs to be installed using the -Pre flag:

PM> Install-Package ServiceStack.OrmLite.MySql.Core -Pre

We'll update the OrmLite MySql package as soon as the first official MySql.Data is released.

Create Tables without Foreign Keys

You can temporarily disable and tell OrmLite to create tables without Foreign Keys by setting:

OrmLiteConfig.SkipForeignKeys = true;

Which can be useful when performing Migrations, Imports or within integration tests.

Custom SqlExpression Filter

The generated SQL from a Typed SqlExpression can now be customized using the new .WithSqlFilter(), e.g:

var q = db.From<Table>()
    .Where(x => x.Age == 27)
    .WithSqlFilter(sql => sql + " option (recompile)");

var q = db.From<Table>()
    .Where(x => x.Age == 27)
    .WithSqlFilter(sql => sql + " WITH UPDLOCK");

var results = db.Select(q);

Custom SQL Fragments

The new Sql.Custom() API lets you use raw SQL Fragments in Custom .Select() expressions, e.g:

var q = db.From<Table>()
    .Select(x => new {
        FirstName = x.FirstName,
        LastName = x.LastName,
        Initials = Sql.Custom("CONCAT(LEFT(FirstName,1), LEFT(LastName,1))")
    });

Other Features

Cached API Key Sessions

You can reduce the number of I/O Requests and improve the performance of API Key Auth Provider Requests by specifying a SessionCacheDuration to temporarily store the Authenticated UserSession against the API Key which will reduce subsequent API Key requests down to 1 DB call to fetch and validate the API Key + 1 Cache Hit to restore the User's Session which if you're using the default in-memory Cache will mean it only requires 1 I/O call for the DB request.

This can be enabled with:

Plugins.Add(new AuthFeature(...,
    new IAuthProvider[] {
        new ApiKeyAuthProvider(AppSettings) {
            SessionCacheDuration = TimeSpan.FromMinutes(10),
        }
    }));

Config.AllowFilePaths

The new Config.AllowFilePaths allows finer-grained file access that lets you use a Glob wildcard pattern to allow access to matching file paths, e.g:

SetConfig(new HostConfig {
    AllowFilePaths = new List<string> {
        "jspm_packages/**/*.json"
    }    
})

Which will tell ServiceStack to allow access to any *.json file under the /jspm_packages folder to avoid having to add "json" to AllowFileExtensions which would open up access to every *.json file.

This feature makes use of the new .GlobPath() extension method which may be useful to use in your own Apps, e.g:

"dir/a/b/c/d/e/file.json".GlobPath("dir/**/*.json") == true

v4.5.2 Release Notes