owin / owin.dll

OWIN defines a standard interface between .NET web servers and web applications.
http://owin.org/
Apache License 2.0
162 stars 19 forks source link

Move IAppBuilder to Microsoft.Owin #19

Closed panesofglass closed 10 years ago

panesofglass commented 10 years ago

IAppBuilder is not part of the OWIN spec and should not be included in an owin.dll. This just confuses people new to OWIN.

tugberkugurlu commented 10 years ago

-1. If it's going to be moved, Project Katana is not the place for that.

Tratcher commented 10 years ago

I agree it causes some confusion, but IAppBuilder can't be moved without resetting the ecosystem. I also wouldn't want to move it until there was an official replacement, so we could avoid breaking the world twice.

I also agree with Tugber, Microsoft.Owin is not the pace to put it. Owin Contrib, in something named Owin.AppBuilder might work.

panesofglass commented 10 years ago

What uses this outside Katana? It is, as far as I know, Katana specific.

panesofglass commented 10 years ago

Also, there can be no replacement for an undefined spec. That this assembly exists is an historical accident/mistake.

half-ogre commented 10 years ago

I see two problems here:

  1. IAppBuilder has become the default "spec" for an OWIN builder. We really need a proper spec for a builder that is as flexible as OWIN itself (e.g., doesn't favor class construction as a means for context).
  2. That builder interface is being shipped in a DLL and NuGet package named OWIN, when it's not OWIN but a builder interface.

I'd like to see a proper builder spec written so we have a consistent way to use middleware with hosts. And, like OWIN, it shouldn't be dependent on type creation (but neither should prevent it). Renaming the DLL and the NuGet package would be good, but it doesn't solve the actual problem of IAppBuilder being a poor "spec". It should really be removed completely once a proper builder spec is produced. And if we want a rich host ecosystem, we need a proper builder spec so we're all consistently building our middlewares.

panesofglass commented 10 years ago

This is a simple matter of versioning. Owin.dll 2.0 = empty assembly :)

Tratcher commented 10 years ago

How about taking this to the owin discussion list instead?

panesofglass commented 10 years ago

I disagree that we need a builder spec. I agree we should finally define a standard for chaining these things, since that seems to be a pain point for some.

Mark's delegate works, as does

Func<AppFunc, AppFunc>
tugberkugurlu commented 10 years ago

@panesofglass forgive my ignorance but what problem do we solve if we don't have a builder spec?

+1 to @half-ogre IMO. Not having a really concrete spec for builder is what is the cause of the problem. Even making the IAppBuilder a spec would solve 90% of the problems (I agree that it's not ideal, though).

half-ogre commented 10 years ago

I agree we should finally define a standard for chaining these things, since that seems to be a pain point for some.

That's a builder spec.

panesofglass commented 10 years ago

@tugberkugurlu why do we need a builder? That is an implementation detail, not part of OWIN.

half-ogre commented 10 years ago

How about taking this to the owin discussion list instead?

I'm obviously biased given where I work, but I much prefer to keep things on a repo where the context lives.

panesofglass commented 10 years ago

I agree with @half-ogre

Tratcher commented 10 years ago

How much of the community is represented here? This affects everybody.

panesofglass commented 10 years ago

@Tratcher Most people are using Microsoft.Owin. I don't understand how moving this interface to Microsoft.Owin breaks people. Everything in Owin.Extensions already moved. How is this different?

Also, please note that we (inclusive of those on the Twitter discussion) are not saying IAppBuilder is evil, bad, etc. It's a Microsoft-specific solution that works just fine within the Katana ecosystem. It's just not a standard for OWIN and shouldn't be owned by nor packaged by OWIN proper. It doesn't work for those of us building alternate implementations and creates a lot of confusion.

If this can't get resolved, it is my opinion that the "Open" in OWIN no longer applies, and we (the community) will have to start working on the next OWIN since this effort appears to have been hijacked.

prabirshrestha commented 10 years ago

+1 for Func<AppFunc, AppFunc> or any other solution that does not include IAppBuilder. +1 for discussing it here. Might be someone should open post a new message in google groups and notify others to watch this repo.

tugberkugurlu commented 10 years ago

@panesofglass MSFT has been putting a lot effort on OWIN based software and building great solutions. Honestly, I don't think I would care that much about the-next-OWIN that "the community" (which I'm not part of apperently :)) will work on.

panesofglass commented 10 years ago

As for who is involved, the Twitter discussion included @skoon, @GrumpyDev, @serialseb, @darrelmiller, @jeremydmiller, @markrendle, and others, covering NancyFx, OpenRasta/OpenHttp, Fubu, Fix/Simple.Web, and Dyfrig/Frank (F#). I'd say that's covering most of the framework community. @markrendle and I also have server libraries that are trying to support OWIN.

tugberkugurlu commented 10 years ago

@panesofglass I need a builder spec so that the host that I'm crafting knows how to wire up the stuff.

Tratcher commented 10 years ago

IAppBuilder was one of the early community proposals, it's not MS specific, it's just the one MS adopted. There are already MS independent implementations out there. It did unfortunately end up in Owin.dll without first being officially approved by the community.

IAppBuilder can be moved to help clear up the confusion, but doing so is going to be a big break because .NET ties type names to assemblies. If we're going to make that break, I'd prefer to have a community replacement ready to move to so we only have to break the world once.

panesofglass commented 10 years ago

@tugberkugurlu Great! Why can't that exist in Katana? It's a great implementation. What's requiring you have that in an Owin.dll?

panesofglass commented 10 years ago

@Tratcher That was @loudej's recommendation. That was never accepted by the community at large. I recall the phone discussions acknowledging that was fine so long as it was not spec. Much of Gate moved to Katana. @bvanderveen helped, of course, but that was all still in the wild west days of the "Delegate of Doom" :tm:

I understand now the impact. Thanks. I'm happy to make the move once we settle on a common replacement.

tugberkugurlu commented 10 years ago

@panesofglass Having a stable software is one thing that I'm all for. If the community you are talking about releases a software which doesn't step outside of the v0.* for years, I'll stick with the MSFT solutions which seem to be pretty robust and have stable release cycles.

I don't think spiting the commutiy into two will solve any of these problems and I don't also think most of the people will care about only community driven the-next-OWIN.

Tratcher commented 10 years ago

Assuming the community can finally standardize the startup sequence, there's no reason Katana would need to keep Owin.dll / IAppBuilder either. We use it for lack of a standard alternative. We don't want to fork the community either.

tugberkugurlu commented 10 years ago

@panesofglass as @half-ogre said:

I agree we should finally define a standard for chaining these things, since that seems to be a pain point for some.

that's the builder spec.

half-ogre commented 10 years ago

@panesofglass as @half-ogre said:

I agree we should finally define a standard for chaining these things, since that seems to be a pain point for some. that's the builder spec.

To be clear, I'm not saying we should specify how a builder is implemented. I'm saying we should specify how a middleware is used in a builder, in the same way OWIN specifies how an app is used (the app delegate).

panesofglass commented 10 years ago

@Tratcher We are in agreement there. I think specifying the startup sequence would be very useful. However, it still has to be fairly generic.

@tugberkugurlu I think it's terrific to use the Microsoft sponsored bits. I've already used Katana on several projects at work, and I'm about to do so again. This is hitting up against another issue, which is interop among OWIN implementations. Most fell behind b/c the v1.0 spec launched forward, and Katana was the first to get there. The rest of us have full-time jobs other than building frameworks. That doesn't mean we should have to fall in line with whatever the first mover decides.

OWIN started as a community-driven solution to a common problem for framework and server devs working on side-projects part-time. Microsoft's involvement is highly prized and appreciated. However, that doesn't mean that they now own OWIN.

We, the community, were willing to break compat with ASP.NET and IIS. I think we would be willing to do so again. I don't think any of us want to do that, but it's not really an issue for us since most of us have far smaller install bases.

Honestly, I am not sure what you are arguing for. You seem to like Katana, and that's great. If Katana satisfies, then what are you proposing? Are you trying to build your own implementation? Do you want to use other implementations? I'm quite confused.

Tratcher commented 10 years ago

So, are we official re-convening the OWIN community to address startup? Finally?

If so, I might also suggest reviving the conference calls. They were very useful the first time around for getting everybody on the same page.

prabirshrestha commented 10 years ago

For reference: Here is a discussion from last year about the IAppBuilder - IAppBuilder in the OWIN spec https://groups.google.com/forum/#!searchin/net-http-abstractions/IAppBuilder/net-http-abstractions/Xy2l71SmYsQ/CUA6VJxDil4J

markrendle commented 10 years ago

I'm up for discussing startup, and getting the middleware story properly sorted too. Let's get it done!

markrendle commented 10 years ago

Oh, and IAppBuilder--.

skoon commented 10 years ago

I think this will always be in contention because we're stuck in CLR land (so to speak) and at SOME point, you've GOT to have a type. Delegates are great for defining the way items communicate, but the types will do all the heavy lifting of passing messages around and setting things up.

Maybe the specification is just that an OWIN compatible host will specify a type that will hoist the app, and that the type will live in an Assembly called Owin.dll?

half-ogre commented 10 years ago

I think this thread is drifting, but:

I have only two goals: don't require a class for middleware, and let middleware be made one way that works everywhere, regardless of the builder or host impl' being used.

A first step toward that could be as simple as deciding on a middleware func and adding a new Use to the IAppBuilder interface: something like IAppBuilder Use(Func<AppFunc, AppFunc> middleware);. That would be backward compatible, and would give middleware makers a simpler, class-free way to make their middleware (that could still work with the old way, too).

To be clear, I don't think that's ideal, but I think it moves us in the right direction without giving up what's already there, and establishes a simpler contract for middleware that will work for other builder and host implementations that don't use IAppBuilder. It moves us toward IAppBuilder being a way to make a builder, not the the way to make a builder. And it means that, as a middleware maker, I'm not required to do anything other than supply a function, keeping in line with OWIN itself.

panesofglass commented 10 years ago

@half-ogre :+1:

Tratcher commented 10 years ago

@half-ogre The docs for IAppBuilder.Use already specify Func<AppFunc, AppFunc>, or at least Func<object, object> https://github.com/owin/owin/blob/master/src/Owin/IAppBuilder.cs

        /// If the middleware given to Use is a Delegate, then it will be invoked with the "next app" in 
        /// the chain as the first parameter. If the delegate takes more than the single argument, 
        /// then the additional values must be provided to Use in the args array.

Middleware have never needed to be IAppBuilder aware, it was just a place where they could advertise via extension method if they wanted.

half-ogre commented 10 years ago

@half-ogre The docs for IAppBuilder.Use already specify Func<AppFunc, AppFunc>, or at least Func<object, object>

The XML doc mentions passing the AppFunc to Use. No IAppBuilder impl' today would handle passing Func<AppFunc, AppFunc>, because it's not expected. That's the problem with Use taking object instead of Func<AppFunc, AppFunc>; unless it's the specific signature, or middleware invocation is properly specified (i.e., not in XML doc), it won't be consistently used.

Middleware have never needed to be IAppBuilder aware, it was just a place where they could advertise via extension method if they wanted.

MIddleware today is very much IAppBuilder aware. You need to take next on your ctor and have a specific Invoke, or you need to pass an AppFunc. Why? Because that's what IAppBuilder understands and requires expects.

half-ogre commented 10 years ago

No IAppBuilder impl' today would handle passing Func<AppFunc, AppFunc>, because it's not expected.

Okay, I might be wrong about that, re-reading this in the XML doc:

/// If the middleware given to Use is a Delegate, then it will be invoked with the "next app" in /// the chain as the first parameter

But I'm not sure what middleware func signature would actually work with that statement, or if any of the app builder implementations would accommodate it. That's the problem with passing object around, and not having a proper spec.

Tratcher commented 10 years ago

The delegate would look something like Func<object, [params]..., object>, where Func<AppFunc, AppFunc> is a valid input. Yes it's vague, we were expecting more variety of middleware (such as System.Net.Http.DelegatingHandler). If we can clarify after a years worth of experience, so much the better.

The constructor pattern outlined in the docs is just an extension of the Func<AppFunc, AppFunc> pattern, next => (AppFunc)new MyType(next).Invoke. Middleware using that pattern are still not concretely tied to IAppBuilder, just compatible with, and can be easily hooked up elsewhere via the Func<AppFunc, AppFunc> pattern.

Tratcher commented 10 years ago

And for reference, both patterns are supported in these implementations: https://katanaproject.codeplex.com/SourceControl/latest#src/Microsoft.Owin/Builder/AppBuilder.cs https://github.com/owin/owin-hosting/blob/master/src/main/Owin.Builder/AppBuilder.cs

half-ogre commented 10 years ago

I gave it a quick test, and can confirm that passing Func<AppFunc, AppFunc> worked beautifully. I feel like a bit of an ass now.

That said, I think it would be very helpful to add a Use overload with a "blessed" middleware func to IAppBuilder, so that middleware makers know, unambiguously, the "lowest common denominator" way to make their middleware that will work with any given builder or host. (I'm not saying that it should be Func<AppFunc, AppFunc>; that's just what I've been playing with). It will also help builder and host makers do the right thing, as XML doc comments are not a normal way to distribute a specification.

Yes it's vague, we were expecting more variety of middleware (such as System.Net.Http.DelegatingHandler). If we can clarify after a years worth of experience, so much the better.

I don't think that time is needed to settle on a middleware func. You can wrap everything else in a function. A delegate function works for the OWIN spec as an LCD, and it would work for middleware use in builders and hosts, too. Heck, if that Use overload had been there, I would have already known this worked.

Tratcher commented 10 years ago

Conceivable. That said, the cost of versioning owin.dll/IAppBuilder is very high (e.g. breaks the world), so we want to wait until there's a definite consensus instead of adding incremental stopgaps.

half-ogre commented 10 years ago

That said, the cost of versioning owin.dll/IAppBuilder is very high (e.g. breaks the world), so we want to wait until there's a definite consensus instead of adding incremental stopgaps.

Why would adding a new Use overload that strongly-types something that's already supposed to work (and is actually working on the most commonly used impls) break anyone?

half-ogre commented 10 years ago

To be clear, I'm talking about like a 2.0 here, not rev'ing 1.0.

half-ogre commented 10 years ago

Now that we've hashed that out, we should probably continue this on the other issue and get back to the original point of this issue, the naming of the .dll and the NuGet package.

Naming this just Owin still feels wrong to me, as it's a builder interface. Even if it is to be the "blessed" OWIN builder interface, it seems like a better name would help, like Owin.Builder (just based on Rack::Builder).

panesofglass commented 10 years ago

It's still not Owin.Builder but Katana.Builder. I would like for us to make that clear. @tugberkugurlu indicated on Twitter that it was clear to him, but most people don't get this.

I would be really happy to have the standard Use take a Func<AppFunc, AppFunc>. I'm also very glad to know that Katana supports this today! If we standardize on that signature, then we should be able to move things forward rather quickly. Or is that wishful thinking?

panesofglass commented 10 years ago

Also, I think some of the reasons for keeping the Func<object, object> around are now gone. HttpMessageHandler doesn't apparently work well from a performance perspective, and most new middlewares have been written directly against OWIN/Katana.

grumpydev commented 10 years ago

Playing devil's advocate here, I'd suggest we take a step back and question whether we even need a unified common interface or "standard" for startup/building the pipeline. Given how every implementation of a host/server will require different bootstrap code (i.e. you don't setup katana asp.net and self hosting the same way, you won't do the same thing with fix or openseb (sorry, don't know what it's called :)) then it's not that big of a step to also include building different as well.

I'm not suggesting everyone go away and do their own thing for the hell of it, but there's no reason why we couldn't have multiple implementations - and make that clear from the naming (e.g. Owin.Builder, Owin.Fixup, etc or something like that) - then from a framework author's PoV it's simple enough for us to have packages that provide the appropriate helper extension methods for each of those "builder types" (Nancy.Owin.Builder, Nancy.Owin.Fixup etc).

Once we get to that point, then whichever proves the most popular/flexible can potentially be the one that becomes part of the spec.

I'd much rather that that spend the next 6 months pontificating on the google group and never actually building anything.. that's arguably what got us to where we are now.

TL;DR - yes, rename it to a convention, provide alternatives, we try and embrace them all, see what floats :beers:

grumpydev commented 10 years ago

For reference, just so there's something concrete to look at (in reference to @half-ogre 's comments), this is Nancy's OWIN host:

https://github.com/NancyFx/Nancy/blob/master/src/Nancy.Owin/NancyOwinHost.cs

It has no dependency or reference on anything - just uses the func signatures - and it handles calling next. Our Nancy.Owin package does (currently) have a reference to Owin though, but that's just so we can have the nice helper extension methods (which I do think are important):

https://github.com/NancyFx/Nancy/blob/master/src/Nancy.Owin/Extensions.cs

So my suggestion would be that we move that extension into Nancy.Owin.Builder (or whatever we call it), and I'd be happy to also create the equivalent for other implementations so everyone gets the nicer pipeline building syntax, regardless of what startup model they're using.

grumpydev commented 10 years ago

Aaaand breath ;)

jeremydmiller commented 10 years ago

Ditto to what Steven said from the fubumvc community. I don't think that a one size fits all startup/bootstrapping mechanism will get a lot of adoption or be terribly useful. Better yet, I think you want to wait and see how this stuff is actually consumed in the various frameworks before standardizing startup and bootstrapping anyway.

On Dec 3, 2013, at 2:02 AM, Steven Robbins notifications@github.com wrote:

Playing devil's advocate here, I'd suggest we take a step back and question whether we even need a unified common interface or "standard" for startup/building the pipeline. Given how every implementation of a host/server will require different bootstrap code (i.e. you don't setup katana asp.net and self hosting the same way, you won't do the same thing with fix or openseb (sorry, don't know what it's called :)) then it's not that big of a step to also include building different as well.

I'm not suggesting everyone go away and do their own thing for the hell of it, but there's no reason why we couldn't have multiple implementations - and make that clear from the naming (e.g. Owin.Builder, Owin.Fixup, etc or something like that) - then from a framework author's PoV it's simple enough for us to have packages that provide the appropriate helper extension methods for each of those "builder types" (Nancy.Owin.Builder, Nancy.Owin.Fixup etc).

Once we get to that point, then whichever proves the most popular/flexible can potentially be the one that becomes part of the spec.

I'd much rather that that spend the next 6 months pontificating on the google group and never actually building anything.. that's arguably what got us to where we are now.

TL;DR - yes, rename it to a convention, provide alternatives, we try and embrace them all, see what floats

— Reply to this email directly or view it on GitHub.