Skip to content

Instantly share code, notes, and snippets.

@steff-mueller
Forked from mythz/draft-notes.md
Created May 20, 2012 08:26
Show Gist options
  • Save steff-mueller/2757307 to your computer and use it in GitHub Desktop.
Save steff-mueller/2757307 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 been our biggest release ever! Mostly of a result of being too busy to prepare the release notes for 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 support in the forums and real-time help 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 and from the response of our users we've started keeping track of this year under @ServiceStack favourites.

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.

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

Filter attributes make a great job when the services get bloated more and more, because you can put the new functionality into a filter attribute and as result the services stay clean. There's also the option to reuse the filter attributes for several services:

    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);
        }
    }

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 we are able to support 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.

Fast IPC Bridge between ServiceStack services & Dart and Node.js processes

In a lot of ways dynamic languages offer many producitivity and flexibility advantages over C#/.NET for web development:

E.g. Node.js (JavaScript on the Server) has superior web tooling (why we've adopted it for Bundler), a larger and thriving OSS ecosystem, excellent libraries and frameworks and is now the 1st-choice platform for many pro-web developers and Start-Ups.

Whilst Dart is the new dynamic structured-language backed by some of the brightest language minds at Google (inc. Lars of V8 fame, Jim Hugunin of Jython/IronPython, Joshua Bloch of Java APIs and Gilad Bracha of JLS/JVM/NewSpeak, amongst others). With unique features like optional-typing, snapshotting, interfaces/default classes and factories and already has great tooling like a lightweight, smart IDE and built-in VM/Debugger in Dartium (a custom Chrome build).

Both Dart and Node.js offer full-webstack programming (i.e. same language on client/server), faster compile and iteration times, less friction and a more lax type-sytem that ultimately offers greater productivity for website development (than static langauges). Node.js/Dart's async/evented architecture also makes it a great choice for web socket communications and highly interactive sites.

We believe statically-typed languages still offer a better value proposition for developing and maintaining web services and is still in many ways a better choice for any CPU-intensive, Data/Binary processing tasks inc. 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 (Razor :) so we have an even less reason for wanting to use ASP.NET MVC :)

Integration with NancyFx

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

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