Difference between middleware and application

229 views
Skip to first unread message

Ali Kheyrollahi

unread,
Jun 10, 2014, 11:43:41 AM6/10/14
to net-http-a...@googlegroups.com
Hi guys,

This is my first here.
So there have been a few niggling things in the back of my mind which I believe needs some work especially now that we are considering v1.1 of spec.

Currently the difference between web app and middleware is poorly defined. Where I stand is that I think there is no difference, an app could be pass through if we think of OWIN HTTP pipeline as a linear structure. One example is a set of apps that each work on a particular route and ignores the rest.

So I am missing something? Anybody else feel the same?

Damian Hickey

unread,
Jun 13, 2014, 5:22:59 AM6/13/14
to net-http-a...@googlegroups.com
Yes, some clarity around this would help. An 'app' for me encompasses everything from the entry AppFunc onwards. 

Some clarity around the fact that middleware can contain inner middleware, and that middleware may be pass-through or terminating would be a good idea too.

Sebastien Lambla

unread,
Jun 14, 2014, 10:30:12 AM6/14/14
to net-http-a...@googlegroups.com
Well I think the “app” is the result of wiring up all the middlewares and the terminal one, through a simple Aggregate starting with null.

I don’t know that there is a need to have a distinction between pass-through middlewares containing other middlewares and middlewares in more complex routes. In the end, once things are wired, there should only be one AppFunc resulting of the aggregation of everything else, no?

--
You received this message because you are subscribed to the Google Groups ".NET HTTP Abstractions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to net-http-abstrac...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Ali Kheyrollahi

unread,
Jun 16, 2014, 11:57:06 AM6/16/14
to net-http-a...@googlegroups.com
> Well I think the “app” is the result of wiring up all the middlewares and the terminal one, through a simple Aggregate starting with null.

I am afraid, not according to the spec. And perhaps this is the best proof that the spec is vague.

"A specific application, possibly built on top of a Web Framework, which is run using OWIN compatible Servers."

So here spec says application is built on top of a Web Framework. If Seb's definition is true then web application can be built on several frameworks. In fact I believe it is the middleware which is based on a single Web Framework.

And Louis believes MW is a decorated app


Current definition is confusing and sloppy and too inexact for a spec.
To unsubscribe from this group and stop receiving emails from it, send an email to net-http-abstractions+unsub...@googlegroups.com.

Damian Hickey

unread,
Jun 16, 2014, 11:59:12 AM6/16/14
to net-http-a...@googlegroups.com

Yep spec needs fixing here. Want to send a PR to the 1.1 MD with better text? :)

You received this message because you are subscribed to a topic in the Google Groups ".NET HTTP Abstractions" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/net-http-abstractions/CB87zpxnbLo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to net-http-abstrac...@googlegroups.com.

Ali Kheyrollahi

unread,
Jun 16, 2014, 12:15:21 PM6/16/14
to net-http-a...@googlegroups.com
By all means Sire! Thanks
To unsubscribe from this group and stop receiving emails from it, send an email to net-http-abstractions+unsubscri...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to a topic in the Google Groups ".NET HTTP Abstractions" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/net-http-abstractions/CB87zpxnbLo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to net-http-abstractions+unsub...@googlegroups.com.

ryan....@panesofglass.org

unread,
Jun 17, 2014, 9:51:46 AM6/17/14
to net-http-a...@googlegroups.com
We have a task to add a middleware spec. We voted on the signature, and based on that can better clarify the differences. In the first round, we did not discriminate between the two. Suggestions on clearer verbiage in the form of a PR are welcome.

To my mind, an App is anything that complies with the AppFunc signature: Func<IDictionary<string, object>, Task>. A middleware is anything that wraps an App and returns a new App: Func<AppFunc, AppFunc>.

Seb’s definition really includes the mechanics of a BuildFunc / builder approach and is not a pure App or Middleware perspective. Even Lou's explanation, though close, is not quite right.

Simplest possible definitions are that the App is immediately callable by an OWIN host/server, i.e. complies with the AppFunc signature. A Middleware is an App decorator. Once the Middleware is called, you now have an App. A Builder would let you declare all the parts and then lazily construct the App to run later.

Examples:

let app1 : AppFunc = App()
let mid1 : MidFunc = Mid1()
let mid2 : MidFunc = Mid2()

let app2 : AppFunc = mid1.Invoke(app1)
let app3 : AppFunc = mid2.Invoke(app2)

let builder : BuildFunc = new Builder().Use(mid2).Use(mid1).Use(Func<_,_>(fun _ -> app1.Invoke()))
let app4 : AppFunc = builder.Invoke()

Sent from Windows Mail

To unsubscribe from this group and stop receiving emails from it, send an email to net-http-abstrac...@googlegroups.com.

djidja8

unread,
Jun 18, 2014, 10:20:07 AM6/18/14
to net-http-a...@googlegroups.com
I, personally, prefer to clearly (at the assembly level) separate middleware from the server and the application.
That makes it easier to work with for a bigger team, and when potentially,
application teams are not the same as server and/or middleware team. Owin spec is very
flexible so that is easy. In my case, this would look something like this:

//--------------------------------------------
namespace Demo.Runner {
  internal static class Program {
    static void Main() {
      var host = new Host(Configurator.ConfigurePipeline());
      host.AddServer("RequestResponse", new NowinServer(8080));
      host.Run();

      Console.WriteLine("Listening on port 8080. Enter to exit.");
      Console.ReadLine();
      host.Stop();
    }
  }
}

//--------------------------------------------
namespace Demo.Middleware {
  public class ResourceResolver : MiddlewareBase {
    protected override Task Process(IContext context) {...}
  }
  //...

  public static class Configurator {
    public static Pipeline ConfigurePipeline() {
      var _pipeline =
        new Pipeline()
                      .Use(new ResourceResolver())
                      .Use(new HypermediaValidator())
                      .Use(new ApiCall())
                      .Use(new HypermediaUpdater())
                      .Use(new HALSerializer());
      return _pipeline;
    }
  }
}

and then application is something like this:

//--------------------------------------------
using SimplR.Resources;
using SimplR.Hypermedia;
using SimplR.Services;
using Demo.Users.Domain;

namespace Demo.Users.Resources {
  public class UsersResource : Resource<User> {
    public override List<User> Get() {...}
    public override User Get(int id) {...}
    public override User Post(User user) {...}
    public override User Put(User user) {...}
    public override void Delete(int id) {...}
  }

  //...

Sebastien Lambla

unread,
Jun 19, 2014, 7:06:46 AM6/19/14
to net-http-a...@googlegroups.com
I assume your middleware base class provides the conversion from Env to IContext?

Way I see it, Server/Host-> AppFunc. The fact that AppFunc may be a framework, may be a framework with decorators, or that all are decorators and AppFunc is just a env=>MidFunc(null) is dependent on having MidFunc. So I think in the new MidFunc world it makes sense to change the text, but how you slice and dice it, which assemblies it lives in or how you do the actual wireup is really out of the scope of the spec.

Let’s fix the text to make this more palpable and explain this more explicitly as we do the updates for MidFunc and BuildFunc?


Alexander Trauzzi

unread,
Jun 21, 2014, 11:40:21 PM6/21/14
to net-http-a...@googlegroups.com
I've been catching up on some of the discussions going on and I'm finding the use of the terms "middleware" and "app" to be very difficult to grasp.
I think some of the points going on here would do well to be accompanied by some very broad-strokes topology diagrams.  Perhaps some of the usages of the terminology are not consistent with what's found in the wild.

Does OWIN really need anything more than the environment dictionary and a middleware function signature?  I think one of the merits enjoyed by other standards like OWIN is that they don't abstract anything more than what's necessary.  

Beyond all this, it seems like OWIN is already out the door according to vNext and yet there's a lot of discussion going on here like as if it isn't.

Very confusing at the moment, perhaps someone could do some kind of summary and try to keep the current state of the spec up to date on the site?  Again - diagrams would speak volumes...


- Alex

Ryan Riley

unread,
Jun 21, 2014, 11:44:49 PM6/21/14
to net-http-a...@googlegroups.com
In short, “middleware” follows the Decorator design pattern. A middleware wraps an app and is itself an app. The function signature is probably what causes the confusion.

I believe the need for documenting this at all is to provide a standard expectation for sharing middleware written in an OO fashion. I wonder if AppDecorator would be a better term.

Ryan

To unsubscribe from this group and stop receiving emails from it, send an email to net-http-abstrac...@googlegroups.com.

Ryan Riley

unread,
Jun 21, 2014, 11:47:11 PM6/21/14
to net-http-a...@googlegroups.com
Also, I should point out that the current state of the spec is on the site, including the draft of 1.1 on which we are currently working. OWIN is definitely out the door, as you say. Could you elaborate on which parts of the discussion make it sound as though it isn’t already live? Most of the chatter in the last months has been a result of confusion around certain aspects and a lack of consistency in how middleware has been implemented to date.

Ryan

On Jun 21, 2014, at 10:40 PM, Alexander Trauzzi <atra...@gmail.com> wrote:

To unsubscribe from this group and stop receiving emails from it, send an email to net-http-abstrac...@googlegroups.com.

Ryan Riley

unread,
Jun 21, 2014, 11:52:31 PM6/21/14
to net-http-a...@googlegroups.com
Also, we are happy to take pull requests if you have any artistic skill. What sort of diagrams would you like to see? I can’t think of anything useful. As you say, OWIN is about as simple as it gets. I like the look of middleware chaining in F#:

let authorize app = …
let log app = …
let appCore environment = …

let app : Environment -> Task = appCore |> authorize |> log (* outermost middleware *)
// or
let app : Environment -> Task = log( authorize( appCore ) )

On Jun 21, 2014, at 10:40 PM, Alexander Trauzzi <atra...@gmail.com> wrote:

To unsubscribe from this group and stop receiving emails from it, send an email to net-http-abstrac...@googlegroups.com.

Alexander Trauzzi

unread,
Jun 22, 2014, 7:58:07 AM6/22/14
to net-http-a...@googlegroups.com
Why can't you just have one term "middleware" and do away with "app". Which to me seems outside the scope of a spec like this?

Angel Java Lopez

unread,
Jun 22, 2014, 9:23:28 AM6/22/14
to net-http-a...@googlegroups.com
I'm not an Owin "expert", only lurking in the project ;-)

AFAIR, Node.js/Express/Connect land, 'app' concept is reserved to what is IAppBuilder in OWIN. Then, all other parts are middleware (with app.use(middleware)).

There is no app.run(....)

Maybe, app.Run(...) is an easy way to add something to the end of chain, a quick way to add a middleware that won't invoke next.

Notably, in Express you can put:

app.use('/admin', appadmin);

where appadmin is another 'app' (IAppBuilder in OWIN, I guess). So you can compose apps: all incoming routs with /admin prefix go to the appadmin. And the programmer of appadmin has no notice of the prefix (usually is removed, there is a way to not be removed). I'm not sure if it is supported in OWIN.

Angel "Java" Lopez
@ajlopez





On Sun, Jun 22, 2014 at 8:58 AM, Alexander Trauzzi <atra...@gmail.com> wrote:
Why can't you just have one term "middleware" and do away with "app".  Which to me seems outside the scope of a spec like this?

Ryan Riley

unread,
Jun 22, 2014, 10:37:18 AM6/22/14
to net-http-a...@googlegroups.com
IAppBuilder is not part of OWIN, thus part of the confusion. This makes me think we need to better clarify the point of OWIN, to provide a shared interface that allows us to separate apps and hosts. In that light, OWIN is more like a CGI for .NET, closer to WSGI than Rack or connect. A middleware is really then just a decorator, and the app signature remains central. The notion of a common builder syntax is still in development, but it is just a means of allowing a lazy construction of an app for OO languages and patterns.

From: Angel Java Lopez
Sent: ‎6/‎22/‎2014 8:23 AM
To: net-http-a...@googlegroups.com
Subject: Re: Difference between middleware and application

Ryan Riley

unread,
Jun 22, 2014, 10:39:17 AM6/22/14
to net-http-a...@googlegroups.com
If anything, middleware and builders are slightly outside of scope. You could create those in any number of ways and still arrive at the important definitions provided in the spec. The only reason for defining middleware and builder patterns is to ensure that OO-style implementations can work across different libraries.

From: Alexander Trauzzi
Sent: ‎6/‎22/‎2014 6:58 AM

To: net-http-a...@googlegroups.com
Subject: Re: Difference between middleware and application

Alexander Trauzzi

unread,
Jun 22, 2014, 10:17:40 PM6/22/14
to net-http-a...@googlegroups.com
Gotcha.  I don't know if this idea has been floated already, but I think it might make sense to have two specs here.  One for the OWIN "app" spec and another for the OWIN "middleware convention" spec.
To unsubscribe from this group and stop receiving emails from it, send an email to net-http-abstractions+unsub...@googlegroups.com.

Ryan Riley

unread,
Jun 22, 2014, 10:23:39 PM6/22/14
to net-http-a...@googlegroups.com
Yes, I agree. That’s exactly what I proposed. I think I’m supposed to write it, but I’ve been a bit swamped with work of late and asked in the GitHub issue if anyone would like to try their hand. If not, I should be able to get around to it in mid-July.


To unsubscribe from this group and stop receiving emails from it, send an email to net-http-abstrac...@googlegroups.com.

Ali Kheyrollahi

unread,
Jun 23, 2014, 8:22:42 AM6/23/14
to net-http-a...@googlegroups.com
I agree with Ryan (and possibly Seb?) that App is the whole thing - composed of all different middlewares. As such App <--> Framework cannot be correct: app can mix different frameworks and probably MW <---> Framework.

My view is that there is no need for builder function since they are framework dependent. There can be many builders, each suited to their own frameworks. Having said that, we need MW and pipeline interfaces defined. which seems you have already done??



On Thursday, 19 June 2014 12:06:46 UTC+1, SerialSeb wrote:
I assume your middleware base class provides the conversion from Env to IContext?

Way I see it, Server/Host-> AppFunc. The fact that AppFunc may be a framework, may be a framework with decorators, or that all are decorators and AppFunc is just a env=>MidFunc(null) is dependent on having MidFunc. So I think in the new MidFunc world it makes sense to change the text, but how you slice and dice it, which assemblies it lives in or how you do the actual wireup is really out of the scope of the spec.

Let’s fix the text to make this more palpable and explain this more explicitly as we do the updates for MidFunc and BuildFunc?


On Tuesday, June 10, 2014 11:43:41 AM UTC-4, Ali Kheyrollahi wrote:
Hi guys,

This is my first here.
So there have been a few niggling things in the back of my mind which I believe needs some work especially now that we are considering v1.1 of spec.

Currently the difference between web app and middleware is poorly defined. Where I stand is that I think there is no difference, an app could be pass through if we think of OWIN HTTP pipeline as a linear structure. One example is a set of apps that each work on a particular route and ignores the rest.

So I am missing something? Anybody else feel the same?

-- 

Sebastien Lambla

unread,
Jun 23, 2014, 9:48:53 AM6/23/14
to net-http-a...@googlegroups.com
Discovery?

Ali Kheyrollahi

unread,
Jun 23, 2014, 10:40:08 AM6/23/14
to net-http-a...@googlegroups.com
Discovery in what terms? 
If app is just the pipeline, whoever sets up the pipeline, knows about all components/MWs. 

As I said, I feel MW is framework dependent hence standardising builder and MW is out of scope. But defining a MW base class and pipeline is important.
I see MW as:

abstract class Middleware
{

   public Middleware(AppFunc next) { ... }

   protected virtual Task XXXAsync(IDictionary<string, object> context)
  {
     if(_next==null)
       return Task.FromResult<object>(null);
     else
       return next();

Sebastien Lambla

unread,
Jun 23, 2014, 10:41:22 AM6/23/14
to net-http-a...@googlegroups.com
Also note that the scope of BuildFunc is only to provide a way to pass a midfunc and share application-level properties, nothing to do with how things are wired internally, the builder implementation really doesn’t care ver much.

For those not wanting to go through all the emails about this, I am pretty much set on using BuildFunc = Action<Func<IDictionary<string,object>, MidFunc>>. and having extension methods called UseXxx for discovery on top of that BuildFunc. The initial code path (Startup.cs) is still the same, controlled by whatever the host wants to do, and this gives a path forward for CommonKeys and associated oddities.

Of course as long as there is a MidFunc for middleware, should you decide not to use a builder supporting BuildFunc, then you can do that manually, and if you do provide the extension method for discoverability then you don’t have a dependency. The fact that BuildFunc is optional but self-contained and pretty much free is why I suggest it be an optional section in the middleware spec, the value of discoverabililty being high enough to stand on its own legs. And if it doesn’t stick and IBuilder wins, then at least we will have tried to match IAppBuilder with a proper replacement.

Doing nothing after removing IAppBuilder is not a solution, it’s losing traction, giving away control and eventually defeating the decoupling target of owin by reintroducing coupling on something else.


Sebastien Lambla

unread,
Jun 23, 2014, 10:42:32 AM6/23/14
to net-http-a...@googlegroups.com
See other email. Discoverability = I add the nuget package for a middleware, then have to figure out how to get from object to MidFunc for each of them, making those non-discoverable.

Mark Rendle

unread,
Jun 25, 2014, 5:48:51 AM6/25/14
to net-http-a...@googlegroups.com
+1 to all points, but especially the part about losing traction.

Mark Rendle
Founder, Zudio

Damian Hickey

unread,
Jun 25, 2014, 7:37:18 AM6/25/14
to net-http-a...@googlegroups.com

Should BuildFunc be a part of the MidFunc spec, or a separate spec? Think I'd prefer the latter myself.

Sebastien Lambla

unread,
Jun 25, 2014, 9:41:31 AM6/25/14
to net-http-a...@googlegroups.com
I’d make it an optional part of the MidFunc spec:

A. MidFunc signature (MUST)
B. Discoverability
    1. Using UseXx extension methods (SHOULD)
        a. The BuildFunc signature

That would allow us to extend the 1 to a 2 (say, a type with a constructor taking IDictionary<string,object> and AppFunc next with an invoke method, or other patterns we may recommend) and to extend a into a b when and if IBuilder with AssemblyNeutral works and is deployed.

Reply all
Reply to author
Forward
0 new messages