+ All Categories
Home > Technology > A Minimalist’s Attempt at Building a Distributed Application

A Minimalist’s Attempt at Building a Distributed Application

Date post: 24-May-2015
Category:
Upload: resources-global-professionals
View: 3,838 times
Download: 0 times
Share this document with a friend
Description:
For a typical .NET developer, building a distributed application of web pages and services involves using IIS. But do you really need a full blown web server like IIS? Building a functional distributed application outside IIS is possible and quite easy. Inspired by lightweight frameworks like Java's Jetty and Python's Bottle, we'll look at creating lightweight sites and services in .NET using Nancy. We'll see how using lightweight frameworks allow you to focus on your business logic without letting heavyweight frameworks and processes get in the way.
Popular Tags:
26
Thanks to our AWESOME sponsors!
Transcript
Page 1: A Minimalist’s Attempt at Building a Distributed Application

Thanks to our AWESOME sponsors!

Page 2: A Minimalist’s Attempt at Building a Distributed Application

A Minimalist’s Attempt at Building a Distributed Application

David Hoerster

Simplist’sControl Freak’s

Page 3: A Minimalist’s Attempt at Building a Distributed Application

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 – [email protected]

Page 4: A Minimalist’s Attempt at Building a Distributed Application

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

Page 5: A Minimalist’s Attempt at Building a Distributed Application

What Do These Have in Common?

Run from a consoleFull featured web app aspectsNo need for IIS or installed web serverJenkins/Solr are JVM; Raven is .NET

Page 6: A Minimalist’s Attempt at Building a Distributed Application

My Project

Have a demo app for using Solr in .NET

Works great, but dependent on IIS

Want to make it more like Solr Install anywhere

Easy to set up and get running

Very configurable

Multiple instances running

IIS(WP)

Solr

SQL

ClientNancy(.EXE)

Page 7: A Minimalist’s Attempt at Building a Distributed Application

Is IIS Evil?

No!

But…

Not everything

requires a hammer

Page 8: A Minimalist’s Attempt at Building a Distributed Application

Basic ASP.NET MVC Operation

public class QuoteController : Controller {

private readonly QuoteRepository _repo;

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

}

Controller derives from Controller

Specific return types

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

Web API improves on this with declared returntypes (e.g. List<T>) and Web API 2 will haveannotated routes (which takes a lot from Nancy).

Page 9: A Minimalist’s Attempt at Building a Distributed Application

What About Bottle (Python)?

@bottle.route('/quote')def get_all_quotes():

l = solr.query(‘*:*’)

# do some Python projection here to get ll

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

Here’s my route

Intuitive method name

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

Page 10: A Minimalist’s Attempt at Building a Distributed Application

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

Page 11: A Minimalist’s Attempt at Building a Distributed Application

Get Quotes in Nancy

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

Get["/quote"] = _ => { var quotes = _repo.GetAll();

return View["Index.cshtml", quotes]; };

}}

Here’s my route and method

Returning dictionary with template and model

Page 12: A Minimalist’s Attempt at Building a Distributed Application

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

Page 13: A Minimalist’s Attempt at Building a Distributed Application

Modules and Routing

Modules are like Controllers

Contain routes and route rules

Essentially all defined in Module constructor

Watch that business logic doesn’t creep in Modules could get unwieldy

public class QuoteModule : NancyModule { private readonly QuoteRepository _repo; public QuoteModule() { _repo = new QuoteRepository();

Get["/quote"] = _ => { var quotes = _repo.GetAll();

return View["Index.cshtml", quotes]; };

}}

Page 14: A Minimalist’s Attempt at Building a Distributed Application

Modules and Routing

What happens here? http://localhost/quote/100 (GET)

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

In MVC, what’s my action?Needs to be part of the route, unless default

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

Nancy has dictionaries for actions

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

Page 15: A Minimalist’s Attempt at Building a Distributed Application

Modules and Routing

Nancy’s routing is based on Method

Pattern

Action

Condition (routes can have conditions)

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

/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 => {…}

Page 16: A Minimalist’s Attempt at Building a Distributed Application

Finding Modules

Nancy scans app for NancyModules

Loads them

No need to define routes in config or global

Nancy favors convention over configuration generally

Page 17: A Minimalist’s Attempt at Building a Distributed Application

Changing Behavior

Nancy is a pipeline

Series of events for each request Want forms authentication?

Add it to the pipeline

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

Auth ErrorHandler

CustomBeforeActions

Request

Module

Page 18: A Minimalist’s Attempt at Building a Distributed Application

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

Page 19: A Minimalist’s Attempt at Building a Distributed Application

Authentication

By default, none

Forms Authentication module is available Get it from NuGet

Somewhat bare bones, but gets the job done

Configure through Bootstrapper

var formsAuthCfg =new FormsAuthenticationConfiguration()

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

FormsAuthentication.Enable(pipelines, formsAuthCfg);

Page 20: A Minimalist’s Attempt at Building a Distributed Application

Content Negotiation

Nancy detects the Accept header on a request

If applicable, will return data in that form

Default formats are JSON

XML

View

Also configurable via Bootstrapper

Gotcha! XML needs to be materialized, not deferred (List<> vs. IEnumerable<>)

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

.Quotes

.ToList(); };

Page 21: A Minimalist’s Attempt at Building a Distributed Application

Dependency Injection

By default, TinyIoc is built in 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

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

How did this get here?

Page 22: A Minimalist’s Attempt at Building a Distributed Application

Performance (Requests/Second)

SU-20-1 SU-100-1 SU-500-1 MU-50-5 MU-100-10 MU-500-5 MU-1000-10 -

20.00

40.00

60.00

80.00

100.00

120.00

140.00

160.00

NancyFX and IIS 8.5 Requests/Second

NancyFX IIS 8.5

Page 23: A Minimalist’s Attempt at Building a Distributed Application

Performance (Time/Request)

SU-20-1 SU-100-1 SU-500-1 MU-50-5 MU-100-10 MU-500-5 MU-1000-10 -

5.00

10.00

15.00

20.00

25.00

30.00

35.00

40.00

45.00

50.00

NancyFX and IIS 8.5 Time (ms)/Request

NancyFX IIS 8.5

Page 24: A Minimalist’s Attempt at Building a Distributed Application

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

Page 25: A Minimalist’s Attempt at Building a Distributed Application

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


Recommended