SlideShare a Scribd company logo
Thanks to our
AWESOME
sponsors!
ControlFreak’s
Simplist’s
A Minimalist’s Attempt at
Building a Distributed
Application
David Hoerster
About Me
 C# MVP (Since April 2011)
 Sr. Director of Web Solutions at RGP

 Conference Director for Pittsburgh TechFest
 Co-Founder of BrainCredits (braincredits.com)
 Past President of Pittsburgh .NET Users Group and organizer of recent Pittsburgh Code Camps and
other Tech Events
 Twitter - @DavidHoerster
 Blog – http://geekswithblogs.net/DavidHoerster
 Email – david@agileways.com
The Minimalist’s Goals
 Easy setup and install
 Able to deploy almost anywhere (low dependency)

 Contained intent
 Anti-Scavenger Hunt Development

 Convention favored over heavy configuration
 But I have control if needed

 No significant performance hit
 Improvement preferred!

 PhD not required
What Do These Have in Common?

Run from a console
Full featured web app aspects
No need for IIS or installed web server
Jenkins/Solr are JVM; Raven is .NET
My Project

 Have a demo app for using Solr in .NET

Solr

 Works great, but dependent on IIS
 Want to make it more like Solr
 Install anywhere

Client

Nancy
IIS
(.EXE)
(WP)

 Easy to set up and get running

 Very configurable
 Multiple instances running

SQL
Is IIS Evil?

No!
But…
Not everything

requires a hammer
Basic ASP.NET MVC Operation
Controller derives from
Controller

public class QuoteController : Controller {

Specific return types

private readonly QuoteRepository _repo;
public ActionResult Index() {
var quotes = _repo.GetAll();
return View(quotes);
}

}
Helpers that do help…
But what’s the route??
(Have to look in global.asax.)

Web API improves on this with declared return
types (e.g. List<T>) and Web API 2 will have
annotated routes (which takes a lot from Nancy).
What About Bottle (Python)?

Here’s my route
Intuitive method name

@bottle.route('/quote')
def get_all_quotes():
l = solr.query(‘*:*’)
# do some Python projection here to get ll

Tells I’m returning a
template, what the
template is, and what
model(s)

return bottle.template(‘quotes_template', dict(myquotes=ll))
Simplicity over Power

 ASP.NET MVC (and Web API) has a lot of power

 With power comes great responsibility
 Conform
 Sometimes lose intuitiveness of code
 Routes defined elsewhere
 Changing in Web API

 Other configuration throughout app
Get Quotes in Nancy
public class QuoteModule : NancyModule {
private readonly IQuoteRepository _repo;
public QuoteModule(IQuoteRepository repo) {
_repo = repo;
Here’s my route and method

Get["/quote"] = _ =>
{
var quotes = _repo.GetAll();
return View["Index.cshtml", quotes];
};

Returning dictionary with
template and model
}
}
Nancy Differences with ASP.NET MVC
 Simple design to create web methods
 No method names – dictionary of routes and funcs
 Route configuration right in with method definitions
 Good or bad? Hmmm….

 Bare bones distributed service environment
 Low overhead / low ceremony service definitions
 Not heavy on configuration

 However, full async/await support not there…yet
Modules and Routing

 Modules are like Controllers
 Contain routes and route rules

public class QuoteModule : NancyModule {
private readonly QuoteRepository _repo;
public QuoteModule() {
_repo = new QuoteRepository();
Get["/quote"] = _ =>
{
var quotes = _repo.GetAll();
return View["Index.cshtml", quotes];
};

 Essentially all defined in Module constructor
 Watch that business logic doesn’t creep in
 Modules could get unwieldy

}
}
Modules and Routing
In MVC, what’s my action?
Needs to be part of the route, unless default
 What happens here?
 http://localhost/quote/100 (GET)

http://localhost/quote/100 (GET)
http://localhost/quote/delete/100 (DELETE)

 http://localhost/quote/100 (DELETE)

Nancy has dictionaries for actions
Get[“/quote/{id}”] = args => { … }
Delete [“/quote/{id}”] = args => { … }
Modules and Routing

 Nancy’s routing is based on
 Method

Get[“/quote/{id}”] = args => { … }
Delete [“/quote/{id}”] = args => { … }

 Pattern
 Action

 Condition (routes can have conditions)

/quote/getall
/quote/{id?} (optional capture segment)
/quote/(?<id>[a..zA..Z]*) (regex)
Post[“/quote”, x => x.id > 0] = args => {…}
Post[“/quote”, x => x.id < 0] = args => {…}
Finding Modules

 Nancy scans app for NancyModules
 Loads them
 No need to define routes in config or global
 Nancy favors convention over configuration generally
Changing Behavior
 Nancy is a pipeline
 Series of events for each request

Request

 Want forms authentication?
 Add it to the pipeline

Auth

Error
Handler

Custom

Before
Actions

 Want custom error page
 Add it to the pipeline

 Steps can be added at application, module and route level
 Allows fine grain control for distributed app dev

Module
Changing Behavior

 Creating a custom bootstrapper allows for custom behavior at app level

 Before and After Hooks for application and module
 Logging and events

 Page Handlers for page type specific behavior
 Handle custom 404’s

 Static files
 If outside of /Content, need to configure in Bootstrapper

pipelines.BeforeRequest += (ctx) =>
{
Logger.Log("starting…");
Command.Enqueue(new Command());
return null;
};
pipelines.AfterRequest += (ctx) =>
{
Logger.Log("ending request");
};
Authentication

 By default, none

 Somewhat bare bones, but gets the job done

var formsAuthCfg =
new FormsAuthenticationConfiguration()
{
RedirectUrl = "~/login",
UserMapper = container.Resolve<IUserMapper>(),
};

 Configure through Bootstrapper

FormsAuthentication.Enable(pipelines, formsAuthCfg);

 Forms Authentication module is available
 Get it from NuGet
Content Negotiation
 Nancy detects the Accept header on a request
 If applicable, will return data in that form
 Default formats are
 JSON
 XML
 View

Get["/api/quote"] = _ =>
{
return _repo.GetAll()
.Quotes
.ToList();
};

 Also configurable via Bootstrapper
 Gotcha! XML needs to be materialized, not deferred (List<> vs. IEnumerable<>)
Dependency Injection

 By default, TinyIoc is built in

private readonly IQuoteRepository _repo;
public QuoteModule(IQuoteRepository repo)
{
_repo = repo;

 Nancy co-developer’s project

 Works well – rated as average on IoC Benchmark by Daniel Palme
 Able to use IoC of choice
 Configure through Bootstrapper

 Example with Ninject

 Built in IoC allows automatic (magic?) injection of instances into Modules

How did this get here?
Performance (Requests/Second)
NancyFX and IIS 8.5 Requests/Second
160.00
140.00

120.00
100.00
80.00
60.00
40.00
20.00
SU-20-1

SU-100-1

SU-500-1

MU-50-5

NancyFX

IIS 8.5

MU-100-10

MU-500-5

MU-1000-10
Performance (Time/Request)
NancyFX and IIS 8.5 Time (ms)/Request
50.00
45.00
40.00
35.00
30.00
25.00
20.00
15.00
10.00
5.00
SU-20-1

SU-100-1

SU-500-1

MU-50-5
NancyFX

IIS 8.5

MU-100-10

MU-500-5

MU-1000-10
The Minimalist’s Goals - Recap
 Easy setup and install
 Able to deploy almost anywhere (low dependency)
 Contained intent
 Anti-Scavenger Hunt Development

 Convention favored over heavy configuration
 But I have control if needed

 No significant performance hit
 PhD not required
What’s Next?

 Nancy + Katana (OWIN)
 Other ASP.NET components moving to pipeline model
 Be able to plug in SignalR and other pieces into Katana
 Great article in MSDN Magazine about Nancy + Katana + SignalR + WebApi

 Custom view renderers

 Custom pipeline components
Resources
 NancyFx Site: http://nancyfx.org/
 Documentation: https://github.com/NancyFx/Nancy/wiki/Documentation
 Howard Dierking on Nancy and Katana: http://msdn.microsoft.com/enus/magazine/dn451439.aspx
 Dependency Injection Rankings: http://www.palmmedia.de/Blog/2011/8/30/ioccontainer-benchmark-performance-comparison
 Session Code: https://github.com/DavidHoerster/Minimalist.Solr
 Slides: http://www.slideshare.net/dhoerster/a-minimalists-attempt-at-building-adistributed-application

More Related Content

PPTX
AngularJS + NancyFx + MongoDB = The best trio for ultimate SPA by Bojan Velja...
PPTX
Latest Javascript MVC & Front End Frameworks 2017
PDF
SxSW 2015
PDF
The MEAN Stack
PDF
ITT Flisol 2013
PPTX
MEAN Stack
PPTX
Learn Developing REST API in Node.js using LoopBack Framework
PDF
Node PDX: Intro to Sails.js
AngularJS + NancyFx + MongoDB = The best trio for ultimate SPA by Bojan Velja...
Latest Javascript MVC & Front End Frameworks 2017
SxSW 2015
The MEAN Stack
ITT Flisol 2013
MEAN Stack
Learn Developing REST API in Node.js using LoopBack Framework
Node PDX: Intro to Sails.js

What's hot (20)

PPTX
Kick start your journey as mern stack developer
PPTX
Mern stack developement
PPTX
Single page application and Framework
PPTX
Single Page Applications: Your Browser is the OS!
PPTX
Introduction to MERN Stack
PDF
From MEAN to the MERN Stack
PPTX
Single Page Application Development with backbone.js and Simple.Web
PDF
JS Framework Comparison - An infographic
PPTX
Introduction to mean stack
PDF
Introduction To Single Page Application
PDF
Building a Single-Page App: Backbone, Node.js, and Beyond
PDF
Frontend as a first class citizen
KEY
SGCE 2012 Lightning Talk-Single Page Interface
PPT
Joomla as a mobile App backend - ideas, examples and experiences
PDF
Introduction to React Native
PPTX
Codegen2021 blazor mobile
PDF
Angular 2 vs React
PPTX
Building Cross Platform Mobile Apps
PPTX
After the LAMP, it's time to get MEAN
PPTX
Web Applications Development with MEAN Stack
Kick start your journey as mern stack developer
Mern stack developement
Single page application and Framework
Single Page Applications: Your Browser is the OS!
Introduction to MERN Stack
From MEAN to the MERN Stack
Single Page Application Development with backbone.js and Simple.Web
JS Framework Comparison - An infographic
Introduction to mean stack
Introduction To Single Page Application
Building a Single-Page App: Backbone, Node.js, and Beyond
Frontend as a first class citizen
SGCE 2012 Lightning Talk-Single Page Interface
Joomla as a mobile App backend - ideas, examples and experiences
Introduction to React Native
Codegen2021 blazor mobile
Angular 2 vs React
Building Cross Platform Mobile Apps
After the LAMP, it's time to get MEAN
Web Applications Development with MEAN Stack
Ad

Similar to A Minimalist’s Attempt at Building a Distributed Application (20)

PPTX
J2EE pattern 5
PPTX
New features of Minimal APIs in .NET 7 -Muralidharan Deenathayalan.pptx
PDF
Intro to Laravel 4
ODP
springmvc-150923124312-lva1-app6892
ODP
Java Spring MVC Framework with AngularJS by Google and HTML5
PPTX
Reactive application using meteor
PPS
Introduction To Mvc
PPTX
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
PPTX
Que hay de nuevo en Visual Studio 2013 y ASP.NET 5.1
PPT
ASP.net MVC CodeCamp Presentation
PPTX
How to perform debounce in react
PDF
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
PDF
WebNet Conference 2012 - Designing complex applications using html5 and knock...
PDF
Angular server side rendering - Strategies & Technics
PDF
Advanced, Composable Collection Views, From CocoaCoders meetup Austin Feb 12,...
PPTX
Working with AngularJS
PPTX
Practical OData
PDF
Data access
PPTX
Asp.net mvc
PDF
Clean Architecture on Android
J2EE pattern 5
New features of Minimal APIs in .NET 7 -Muralidharan Deenathayalan.pptx
Intro to Laravel 4
springmvc-150923124312-lva1-app6892
Java Spring MVC Framework with AngularJS by Google and HTML5
Reactive application using meteor
Introduction To Mvc
AngularJS training - Day 1 - Basics: Why, What and basic features of AngularJS
Que hay de nuevo en Visual Studio 2013 y ASP.NET 5.1
ASP.net MVC CodeCamp Presentation
How to perform debounce in react
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
Angular server side rendering - Strategies & Technics
Advanced, Composable Collection Views, From CocoaCoders meetup Austin Feb 12,...
Working with AngularJS
Practical OData
Data access
Asp.net mvc
Clean Architecture on Android
Ad

More from David Hoerster (10)

PPTX
Elm - Could this be the Future of Web Dev?
PPTX
Reactive Development: Commands, Actors and Events. Oh My!!
PPTX
CQRS Evolved - CQRS + Akka.NET
PPTX
Creating scalable message driven solutions akkadotnet
PPTX
Being RDBMS Free -- Alternate Approaches to Data Persistence
PPTX
Mongo Baseball .NET
PPTX
Freeing Yourself from an RDBMS Architecture
PPTX
Greenfield Development with CQRS and Windows Azure
PPTX
Greenfield Development with CQRS
PPTX
jQuery and OData - Perfect Together
Elm - Could this be the Future of Web Dev?
Reactive Development: Commands, Actors and Events. Oh My!!
CQRS Evolved - CQRS + Akka.NET
Creating scalable message driven solutions akkadotnet
Being RDBMS Free -- Alternate Approaches to Data Persistence
Mongo Baseball .NET
Freeing Yourself from an RDBMS Architecture
Greenfield Development with CQRS and Windows Azure
Greenfield Development with CQRS
jQuery and OData - Perfect Together

Recently uploaded (20)

PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
NewMind AI Monthly Chronicles - July 2025
PPTX
MYSQL Presentation for SQL database connectivity
PPTX
Big Data Technologies - Introduction.pptx
PDF
Machine learning based COVID-19 study performance prediction
PPT
Teaching material agriculture food technology
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
cuic standard and advanced reporting.pdf
PDF
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
PDF
Empathic Computing: Creating Shared Understanding
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PPTX
Cloud computing and distributed systems.
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
PPTX
A Presentation on Artificial Intelligence
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
PDF
Approach and Philosophy of On baking technology
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
Encapsulation_ Review paper, used for researhc scholars
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
NewMind AI Monthly Chronicles - July 2025
MYSQL Presentation for SQL database connectivity
Big Data Technologies - Introduction.pptx
Machine learning based COVID-19 study performance prediction
Teaching material agriculture food technology
20250228 LYD VKU AI Blended-Learning.pptx
cuic standard and advanced reporting.pdf
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
Empathic Computing: Creating Shared Understanding
Advanced methodologies resolving dimensionality complications for autism neur...
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Cloud computing and distributed systems.
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
A Presentation on Artificial Intelligence
Diabetes mellitus diagnosis method based random forest with bat algorithm
Approach and Philosophy of On baking technology

A Minimalist’s Attempt at Building a Distributed Application

  • 2. ControlFreak’s Simplist’s A Minimalist’s Attempt at Building a Distributed Application David Hoerster
  • 3. About Me  C# MVP (Since April 2011)  Sr. Director of Web Solutions at RGP  Conference Director for Pittsburgh TechFest  Co-Founder of BrainCredits (braincredits.com)  Past President of Pittsburgh .NET Users Group and organizer of recent Pittsburgh Code Camps and other Tech Events  Twitter - @DavidHoerster  Blog – http://geekswithblogs.net/DavidHoerster  Email – david@agileways.com
  • 4. The Minimalist’s Goals  Easy setup and install  Able to deploy almost anywhere (low dependency)  Contained intent  Anti-Scavenger Hunt Development  Convention favored over heavy configuration  But I have control if needed  No significant performance hit  Improvement preferred!  PhD not required
  • 5. What Do These Have in Common? Run from a console Full featured web app aspects No need for IIS or installed web server Jenkins/Solr are JVM; Raven is .NET
  • 6. My Project  Have a demo app for using Solr in .NET Solr  Works great, but dependent on IIS  Want to make it more like Solr  Install anywhere Client Nancy IIS (.EXE) (WP)  Easy to set up and get running  Very configurable  Multiple instances running SQL
  • 7. Is IIS Evil? No! But… Not everything requires a hammer
  • 8. Basic ASP.NET MVC Operation Controller derives from Controller public class QuoteController : Controller { Specific return types private readonly QuoteRepository _repo; public ActionResult Index() { var quotes = _repo.GetAll(); return View(quotes); } } Helpers that do help… But what’s the route?? (Have to look in global.asax.) Web API improves on this with declared return types (e.g. List<T>) and Web API 2 will have annotated routes (which takes a lot from Nancy).
  • 9. What About Bottle (Python)? Here’s my route Intuitive method name @bottle.route('/quote') def get_all_quotes(): l = solr.query(‘*:*’) # do some Python projection here to get ll Tells I’m returning a template, what the template is, and what model(s) return bottle.template(‘quotes_template', dict(myquotes=ll))
  • 10. Simplicity over Power  ASP.NET MVC (and Web API) has a lot of power  With power comes great responsibility  Conform  Sometimes lose intuitiveness of code  Routes defined elsewhere  Changing in Web API  Other configuration throughout app
  • 11. Get Quotes in Nancy public class QuoteModule : NancyModule { private readonly IQuoteRepository _repo; public QuoteModule(IQuoteRepository repo) { _repo = repo; Here’s my route and method Get["/quote"] = _ => { var quotes = _repo.GetAll(); return View["Index.cshtml", quotes]; }; Returning dictionary with template and model } }
  • 12. Nancy Differences with ASP.NET MVC  Simple design to create web methods  No method names – dictionary of routes and funcs  Route configuration right in with method definitions  Good or bad? Hmmm….  Bare bones distributed service environment  Low overhead / low ceremony service definitions  Not heavy on configuration  However, full async/await support not there…yet
  • 13. Modules and Routing  Modules are like Controllers  Contain routes and route rules public class QuoteModule : NancyModule { private readonly QuoteRepository _repo; public QuoteModule() { _repo = new QuoteRepository(); Get["/quote"] = _ => { var quotes = _repo.GetAll(); return View["Index.cshtml", quotes]; };  Essentially all defined in Module constructor  Watch that business logic doesn’t creep in  Modules could get unwieldy } }
  • 14. Modules and Routing In MVC, what’s my action? Needs to be part of the route, unless default  What happens here?  http://localhost/quote/100 (GET) http://localhost/quote/100 (GET) http://localhost/quote/delete/100 (DELETE)  http://localhost/quote/100 (DELETE) Nancy has dictionaries for actions Get[“/quote/{id}”] = args => { … } Delete [“/quote/{id}”] = args => { … }
  • 15. Modules and Routing  Nancy’s routing is based on  Method Get[“/quote/{id}”] = args => { … } Delete [“/quote/{id}”] = args => { … }  Pattern  Action  Condition (routes can have conditions) /quote/getall /quote/{id?} (optional capture segment) /quote/(?<id>[a..zA..Z]*) (regex) Post[“/quote”, x => x.id > 0] = args => {…} Post[“/quote”, x => x.id < 0] = args => {…}
  • 16. Finding Modules  Nancy scans app for NancyModules  Loads them  No need to define routes in config or global  Nancy favors convention over configuration generally
  • 17. Changing Behavior  Nancy is a pipeline  Series of events for each request Request  Want forms authentication?  Add it to the pipeline Auth Error Handler Custom Before Actions  Want custom error page  Add it to the pipeline  Steps can be added at application, module and route level  Allows fine grain control for distributed app dev Module
  • 18. Changing Behavior  Creating a custom bootstrapper allows for custom behavior at app level  Before and After Hooks for application and module  Logging and events  Page Handlers for page type specific behavior  Handle custom 404’s  Static files  If outside of /Content, need to configure in Bootstrapper pipelines.BeforeRequest += (ctx) => { Logger.Log("starting…"); Command.Enqueue(new Command()); return null; }; pipelines.AfterRequest += (ctx) => { Logger.Log("ending request"); };
  • 19. Authentication  By default, none  Somewhat bare bones, but gets the job done var formsAuthCfg = new FormsAuthenticationConfiguration() { RedirectUrl = "~/login", UserMapper = container.Resolve<IUserMapper>(), };  Configure through Bootstrapper FormsAuthentication.Enable(pipelines, formsAuthCfg);  Forms Authentication module is available  Get it from NuGet
  • 20. Content Negotiation  Nancy detects the Accept header on a request  If applicable, will return data in that form  Default formats are  JSON  XML  View Get["/api/quote"] = _ => { return _repo.GetAll() .Quotes .ToList(); };  Also configurable via Bootstrapper  Gotcha! XML needs to be materialized, not deferred (List<> vs. IEnumerable<>)
  • 21. Dependency Injection  By default, TinyIoc is built in private readonly IQuoteRepository _repo; public QuoteModule(IQuoteRepository repo) { _repo = repo;  Nancy co-developer’s project  Works well – rated as average on IoC Benchmark by Daniel Palme  Able to use IoC of choice  Configure through Bootstrapper  Example with Ninject  Built in IoC allows automatic (magic?) injection of instances into Modules How did this get here?
  • 22. Performance (Requests/Second) NancyFX and IIS 8.5 Requests/Second 160.00 140.00 120.00 100.00 80.00 60.00 40.00 20.00 SU-20-1 SU-100-1 SU-500-1 MU-50-5 NancyFX IIS 8.5 MU-100-10 MU-500-5 MU-1000-10
  • 23. Performance (Time/Request) NancyFX and IIS 8.5 Time (ms)/Request 50.00 45.00 40.00 35.00 30.00 25.00 20.00 15.00 10.00 5.00 SU-20-1 SU-100-1 SU-500-1 MU-50-5 NancyFX IIS 8.5 MU-100-10 MU-500-5 MU-1000-10
  • 24. The Minimalist’s Goals - Recap  Easy setup and install  Able to deploy almost anywhere (low dependency)  Contained intent  Anti-Scavenger Hunt Development  Convention favored over heavy configuration  But I have control if needed  No significant performance hit  PhD not required
  • 25. What’s Next?  Nancy + Katana (OWIN)  Other ASP.NET components moving to pipeline model  Be able to plug in SignalR and other pieces into Katana  Great article in MSDN Magazine about Nancy + Katana + SignalR + WebApi  Custom view renderers  Custom pipeline components
  • 26. Resources  NancyFx Site: http://nancyfx.org/  Documentation: https://github.com/NancyFx/Nancy/wiki/Documentation  Howard Dierking on Nancy and Katana: http://msdn.microsoft.com/enus/magazine/dn451439.aspx  Dependency Injection Rankings: http://www.palmmedia.de/Blog/2011/8/30/ioccontainer-benchmark-performance-comparison  Session Code: https://github.com/DavidHoerster/Minimalist.Solr  Slides: http://www.slideshare.net/dhoerster/a-minimalists-attempt-at-building-adistributed-application