Skip to content

Instantly share code, notes, and snippets.

@mythz
Created May 20, 2012 07:46
Show Gist options
  • Save mythz/2757233 to your computer and use it in GitHub Desktop.
Save mythz/2757233 to your computer and use it in GitHub Desktop.
draft-notes.md

v3.78 Release Notes

Although it's been a long time between formal releases - v3.78 marks our biggest release ever! Mostly as a result of being too busy to prepare these release notes containing all the effort that have gone into the framework (and supporting libraries) in the last 6 months :)

Today we hope to rectify this neglect with a special thanks to all the contributors that helped make this release possible. We would like to pay a special thanks to Steffen Müller (@arxisos) whose code and documentation contributions and expert support in the forums and real-time help channel over these last 6 months have been invaluable.

A lot of features being announced are already well known to our active user-base as they've shipped in our production release builds for months. Hopefully these notes will highlight other useful but less known features.

Awesome Feedback

We're estatic at the response we've received from the community this year which has seen our Contributor count more than doubled (now at 66 Contributors!). We've also received great response from our users which we've started keeping track of this year under @ServiceStack favourites and in the forums.

New Demo Reference App

Many of these features listed below are showcased in the new Social Bootstrap API reference demo - a Backbone.js-enabled Single Page App (SPA) template, pre-configured with Twitter & Facebook login, with Bundler built-in for super-fast bundling and minification.

The above repo is kindly hosted by AppHarbor at http://bootstrapapi.apphb.com

Tweets

Authentication & Authorization

Probably the biggest features shipped in this release is a 'clean' authentication provider model, completely detached from ASP.NET's existing membership providers exposed as clean interfaces with the following pluggable auth providers supported out-of-the-box:

    Plugins.Add(new AuthFeature(
        () => new CustomUserSession(),             //Use your own typed Custom UserSession type
        IncludeAssignRoleServices = false,         //Don't register AssignRoles/UnAssignRoles services to manage users roles
        new IAuthProvider[] {
            new CredentialsAuthProvider(),         //HTML Form post of UserName/Password credentials
            new TwitterAuthProvider(appSettings),  //Sign-in with Twitter
            new FacebookAuthProvider(appSettings), //Sign-in with Facebook
            new BasicAuthProvider(),               //Sign-in with Basic Auth
            new DigestAuthProvider(),              //Sign-in with Digest Auth
            new CustomCredentialsAuthProvider(),   //Subclass CredentialsAuthProvider and access your own User/Pass repository
        }));

Note: Only the AuthProviders registered on the AuthFeature plugin are available at runtime.

Event Hooks

You can add custom logic to the user Authenticaiton by overriding the OnAuthenticated() method on either the:

  • Custom UserSession - which gets called after every successful Authentication/Login attempt (on any AuthProvider)
  • Custom AuthProvider - which only gets called when a user authenticates with this specific provider

You can also plug-in your own Validation Hooks

  • AuthService.ValidateFn - Called in the context of the AuthService, any C# exceptions are propagated to the client
  • RegistrationService.ValidateFn - Called in the context of the RegistrationService, any C# exceptions are propagated to the client
  • Registration Validator - Override the default Registration validator to add stricter/lax validation logic

Since the new AuthFeature and its related Session classes are pure POCOs we're able to cleanly support multiple back-end session & persistance providers:

Per-Request Session Access (ICacheClient)

  • InMemory
  • Redis (distributed)
  • Memcached (distributed)

Longterm Persistance DataStore

  • OrmLite
    • SqlServer, Sqlite, PostgreSql, MySql and Firebird RDBMS back-ends
  • Redis
  • InMemory (for testing)

Roles & Permissions

The Auth POCOs can hold any number of Roles and Permissions per user.

Which can be used to protect your services by adding the attributes below onto your Service or Request DTOs:

 [RequiredRole(roleNames)]
 [RequiredPermission(permissionNames)]

These attributes can also be used on MVC Controllers as part of the ServiceStack.Mvc NuGet pacakage and is explained in the MVC PowerPack.

These permissions can be managed with the AssignRoles/UnAssignRoles services registered as part of the AuthFeature plugin. Only users with the Admin role can access these services.

More info about autentication can be found in the wiki documentation.

Validators

When you enable the ValidationFeature() plugin you can create a validator for every request DTO you have, with smart, terse fluent syntax that can handle most use-cases, e.g:

    public class UserValidator : UserValidator<ModelToValidate> {
        public UserValidator() {
            //Validation rules for all requests
            RuleFor(r => r.Name).NotEmpty();
            RuleFor(r => r.Age).GreaterThan(0);

            //Only apply this validation logic to POST and PUT requests
            RuleSet(ApplyTo.Post | ApplyTo.Put, () => {
                RuleFor(r => r.Count).GreaterThan(10);
            });
        }
    }

This fluent syntax is provided to you by an integrated version of JeremySkinner's excellent FluentValidation library.

More info about validation can be found in the wiki documentation.

Filter attributes

Request/Response filters (modelled after MVC Action filters) are a great way to share common logic between services which you can easily add by marking your service class or Request/Response DTOs with a Request or Response Filter Attribute. The RequiredRole and RequiredPermission attributes good examples of functionality that's best captured in Filter attributes. Here's a simple example of how to create one:

    public class LogFilterAttribute : RequestFilterAttribute {
        
        public IStatsLogger StatsLogger { get; set; }  // Injected by IOC
          
        public LogFilterAttribute(){
            //Priorities <0 are executed before global filters, filters with priorities >= are executed after (in order)
            base.Priority = 10;
        }

        public override void Execute(IHttpRequest req, IHttpResponse res, object requestDto) {
            //This code is executed before the service
            StatsLogger.SaveUserAgent(req.UserAgent);
        }
    }

That's it! No registration is needed as they're auto-discovered so you can start adding them on services you want to log.

More info about request and response filter attributes can be found in the wiki documentation.

New Plugin API

As of v3.55 all ServiceStack's add-ons now implement the following Plugin API:

    public interface IPlugin {
        void Register(IAppHost appHost);
    }

Plugins registered by default

ServiceStack's CSV Format:

Plugins.Add(new CsvFormat());

ServiceStack's auto generated HTML5 JSON Report Format:

Plugins.Add(new HtmlFormat());  

Razor Markdown Format:

Plugins.Add(new MarkdownFormat());  

More info about Razor Markdown: Intro, Features, Docs Website

Removing or accessing built-in plug-ins

You can prevent a default plug-in from being added by removing it from a list, e.g: removing the CSV Format:

Plugins.RemoveAll(x => x is CsvFormat);

Likewise you can access a plug-in just as easy, should you want to modify their existing attriutes, e.g:

var htmlFormat = (HtmlFormat)base.Plugins.First(x => x is HtmlFormat);

Available plugins

Enable ServiceStack's Fluent Validation:

Plugins.Add(new ValidationFeature());

Enable ServiceStack's built-in Authentication (displayed above in full):

Plugins.Add(new AuthFeature(....));

The AuthFeature above already enables the SessionFeature, but if you want to make use of sessions and don't want to enable the built-in Authentication, you will need to register it manually with:

Plugins.Add(new SessionFeature());

The Registration feature enables the Registration Service and allows users to register at the default route /register:

Plugins.Add(new RegistrationFeature());

Adding the ProtoBuf Format NuGet package automatically adds the ProtoBufFormat plug-in:

Plugins.Add(new ProtoBufFormat());

Add an In-Memory IRequestLogger and service with the default route at /requestlogs which maintains a live log of the most recent requests (and their responses). Supports multiple config options incl. Rolling-size capacity, error and session tracking, hidden request bodies for sensitive services, etc.

Plugins.Add(new RequestLogsFeature());

The IRequestLogger is a great way to introspect and analyze your service requests in real-time. Here's a screenshot from the http://bootstrapapi.apphb.com website:

Live Screenshot

It supports multiple queryString filters and switches so you filter out related requests for better analysis and debuggability:

Request Logs Usage

The RequestLogsService is just a simple C# service under-the-hood but is a good example of how a little bit of code can provide a lot of value in ServiceStack's by leveraging its generic, built-in features.

Messaging services

ServiceStack's typed, message-first design is ideal for coarse-grained out-of-proc communication. Although HTTP is our primary endpoint, through our clean IMessageService interface we also provide a number of alternate hosts that are able to re-use your existing services made available on different hosts.

In many ways MQ's are underrated technology in .NET, but they can provide superior conduit to connect your internal services, especially for async/one-way, idempotent messages. They can offer reliabile and durable messaging, better scalability and natural load-balancing, as well as time-decoupled and disconnected operation between loosely-coupled endpoints.

New hosts can be easily added by implementing the IMessageService interface which is something we plan on doing in the near future. As future hosts will be able to bind to your existing services, you'll be able to easily make use of them when they're ready.

Other changes

There have been lots of other smaller features and fixes added during the time between releases (too many to add here). Although you can check our commit logs if you're interested in the finer details of what we've been up to :)

Future Roadmap

For those interested in our future road-map we hope to ship the following features for our next-release:

Async

As part of his excellent contributions @arxisos has been maintaining an async branch that has ServiceStack running on IHttpAsyncHandler and already has a functional alpha build available for you to try at: ServiceStack-v4.00-alpha.zip

With this change ServiceStack supports Task<> as a return type on services. You only need to register the Task<> plugin. To see a full example look at this integration test.

New Metadata pages

The only way we can support the different layouts and customizations users want to apply to the auto-generated metadata pages is to have them completely customizable and hot-swappable. So that's our plan for the next iteration of the metadata pages - a rewrite into a self-contained, swappable static HTML/Ajax pages. We'll attempt to provide as much info in our json metadata services we can so others are able to create an executable REST API/UI from them - i.e. making it possible to integrate 3rd party OSS REST API clients like Swagger or Apigee.

Fast IPC/RPC Bridge between ServiceStack services <=> C#/.NET, Dart / Node.js processes

As soon as Async has been integrated into ServiceStack core, it will lay the foundation for our work on a fast IPC/RPC bridge between ServiceStack services and external C#/.NET and node.js/Dart processes.

As ServiceStack's message-based design influences the development of coarse-grained (i.e. non-chatty) services it provides the perfect interface for efficient out-of-process communications. We plan to get an optimal implementation by employing an async/non-blocking design, invoking services directly (by-passing the overhead of the HTTP Stack/Context) and using our fast JSON Serializer in .NET and the native JSON parsers in node.js/Dart.

Although our motivations to build a bridge to external C#/.NET processes will be well-understood by our .NET-strong user-base, why we'd want to provide a good story for Dart and node.js platforms will be less clear...

Whoa?.. What are all these node.js and Dart pieces doing in my .NET soup?

In many ways dynamic languages offer greater productivity, flexibility, iteration time advantages over static languages (i.e. C#/.NET) for web development. E.g: Node.js (Server-Side V8/JavaScript) has superior web tooling (with native implementations for all popular web DSLs and minifiers - and why we've adopted it for Bundler), a large and thriving OSS ecosystem, excellent libraries and frameworks making it the 1st-choice platform for many pro-web developers and Start-Ups.

Whilst Dart is the new dynamic structured-language under heavy development by some of the brightest language minds at Google including: Lars Bak, Kasper Lund, Vyacheslav Egorov & Mads Ager (original V8 team), Jim Hugunin (Jython/IronPython/DLR), Joshua Bloch (Java APIs), Gilad Bracha (JLS/JVM/NewSpeak), and many others.

It sports many unique features well suited for the development of complex web apps:

Although the first version is not yet released it already ships with great tooling (for OSX/Win/Linux) including a smart, lightweight IDE and a built-in VM/Debugger in Dartium (a custom build of Chrome).

Both Node.js and Dart offer full-webstack programming (same language used on client/server), faster compile and iteration times, less friction and a more lax type-system - ideal for web development. Node.js and Dart's async/evented architecture also makes it a great choice for web socket servers and highly interactive sites.

Getting the best of both worlds

We still believe statically-typed languages offer a better value proposition for developing and maintaining web services and is still in many ways a better choice for any CPU-intensive, Heavy Data/Binary processing tasks as well as accessing native/unmanaged APIs.

With that said we feel there's a lot of value in developing a great story to efficiently communicate between ServiceStack and node.js/Dart processes which we hope offers the best of both worlds for other like-minded polygots.

Although as ServiceStack has already developed .NET's fastest JSON serializer and .NET's leading C# Redis Client (and Dart Redis Client :) - We already have a great comms story via Redis available today - but we hope to make it even better by communicating directly between .NET/node.js/Dart processes (i.e. by-passing redis).

Potential MVC Razor and spark integration

ServiceStack already has existing HTML Support, but we hope to increase it even further by integrating the best thing we like about MVC (i.e. Razor :) so we have even less reasons for wanting to host ServiceStack with ASP.NET MVC :)

Integration with NancyFx

Nancy is another excellent OSS (ASP.NET MVC Replacement) Web Framework for .NET, that offers a simple, clean and terse programming model for websites (just the kind we like :). We hope to provide a good Social Bootstrap API-like template but replaced with a NancyFx host instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment