New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge Giraffe with Suave #98

Closed
dustinmoris opened this Issue Sep 27, 2017 · 17 comments

Comments

Projects
None yet
@dustinmoris
Member

dustinmoris commented Sep 27, 2017

First of all this issue is only an attempt to move this Twitter thread into a more organised forum which makes it easier to discuss & brainstorm a potential merge of Giraffe with Suave. There are no current plans of merging Giraffe with Suave as of today and this issue should not worry any Suave or Giraffe users!

Ok, now that I got this out of the way l'd like to start this conversation by saying that I am generally very open in merging efforts in every possible way. Having said that I also acknowledge that there are some fundamental differences between Suave and Giraffe (hence why Giraffe was born) and I think it is crucial to get a common ground on these differences and a shared vision before even discussing any technical details on how to achieve such a merge.

One of the main differences between Giraffe and Suave is that Giraffe's fundamental vision, as often stated, is to tightly integrate with ASP.NET Core. It was born to fill the niche where functional .NET devs wanted to build a functional ASP.NET Core web application. Giraffe tries to fill this specific niche by providing a thin layer on top of ASP.NET Core, but keeping the core building blocks of ASP.NET Core alive (DI, HttpRequest, HttpResponse, Config, etc.). This is a very important aspect from my point of view, because I personally believe that this enables F# developers to use a lot of the already existing (and future upcoming) ASP.NET Core ecosystem which is done by the community (F# as well as C# open source projects and MS projects). A good example is Identity, EF, various error reporting or logging frameworks and so on.

This tight integration also made the maintenance of Giraffe fairly trouble free. There was very little critical issues raised so far and very little feature requests which couldn't be implemented with little efforts, because all the heavy work - features like security, logging, web server capabilities, development and debug features, etc. - were already solved for ASP.NET Core by other people and therefore accessible in Giraffe without any additional effort from my side. This is a huge win for me and the community IMHO.

I think all the other benefits which I might have blogged or talked about are sort of inherited from this one single feature. I think it is possible to find a way to make it work with Suave (e.g. Suave could have a dependency on ASP.NET Cores HttpAbstractions), but before going too much into detail I'd be interested to hear @haf and @ademar view points and vision for Suave to see how it fits with Giraffe.

Of course everyone else is welcome to chip in and provide your ideas/views/thoughts on this topic.

@aggieben

This comment has been minimized.

Show comment
Hide comment
@aggieben

aggieben Sep 27, 2017

@dustinmoris thanks for explaining - to people like me who aren't heavily using either, it's very helpful to have that articulation of Giraffe's raison d'être.

My outsider opinion is this: I don't see a need to merge. There's no harm done to the .NET (or even specifically F#) by having multiple viable choices of web framework.

aggieben commented Sep 27, 2017

@dustinmoris thanks for explaining - to people like me who aren't heavily using either, it's very helpful to have that articulation of Giraffe's raison d'être.

My outsider opinion is this: I don't see a need to merge. There's no harm done to the .NET (or even specifically F#) by having multiple viable choices of web framework.

@josselinauguste

This comment has been minimized.

Show comment
Hide comment
@josselinauguste

josselinauguste Sep 27, 2017

Now that Asp.Net Core exists, does it still makes sense for Suave to use its own server implementation? Maybe it is a naive question, but I'm fairly unaware of the Dotnet Core ecosystem.

Maybe the solution would be to have a common functional API layer built upon multiple server implementation layers (.Net Core, custom server, etc.)

josselinauguste commented Sep 27, 2017

Now that Asp.Net Core exists, does it still makes sense for Suave to use its own server implementation? Maybe it is a naive question, but I'm fairly unaware of the Dotnet Core ecosystem.

Maybe the solution would be to have a common functional API layer built upon multiple server implementation layers (.Net Core, custom server, etc.)

@mrkaspa

This comment has been minimized.

Show comment
Hide comment
@mrkaspa

mrkaspa Sep 27, 2017

is the idea to make work Suave with ASP.Net?

mrkaspa commented Sep 27, 2017

is the idea to make work Suave with ASP.Net?

@gerardtoconnor

This comment has been minimized.

Show comment
Hide comment
@gerardtoconnor

gerardtoconnor Sep 27, 2017

Member

@josselinauguste I think a lot of applications still use the simple own server implementation eg Ionide & FSCS, to allow simple micro server instances to be used as app api ... using full dotnet core, due to its heavy caching and pooling would take up a lot of memory in their basic cases, makes sense to keep for these use cases.

Suave currently already has a version built on top of kestrel but due to Giraffes thin middleware and use of Task Continuations over Suave Async Bindings, it performs 50% faster than Suave with Kestral, in line with c# MVC performance, and about 88x faster than Suave's basic server (thanks mostly to Kestral). To create a common functional API layer, Giraffe would have to go back to Async binding but in doing so loose 20% of its speed as it would run into the issues of :

  1. Converting back and forth between Task & Async (additional scheduling)
  2. Wrapping sync values in Async, just to fit in the pipeline (Giraffe never needs to wrap thanks to continuations)

In case anyone is unfamiliar with Giraffe, it's main composable function, comparable to Suave's Webpart is its HttpHandler but the signatures are different:

Suave WebPart (accepts HttpContext) =

type WebPart = HttpContext -> Async<HttpContext option>

Giraffe Httphandler (accepts both a continuation/nextFn & HttpContext)=

type HttpFunc = HttpContext -> Task<HttpContext option>
type HttpHandler = (HttpFunc -> HttpContext) -> Task<HttpContext option> // HttpFunc -> HttpFunc

@mrkaspa I think the idea is to discuss the feasibility of merging Giraffe (that uses ASP.net core) into Suave so that in the end Suave would have an ASP.Net core server option.

Member

gerardtoconnor commented Sep 27, 2017

@josselinauguste I think a lot of applications still use the simple own server implementation eg Ionide & FSCS, to allow simple micro server instances to be used as app api ... using full dotnet core, due to its heavy caching and pooling would take up a lot of memory in their basic cases, makes sense to keep for these use cases.

Suave currently already has a version built on top of kestrel but due to Giraffes thin middleware and use of Task Continuations over Suave Async Bindings, it performs 50% faster than Suave with Kestral, in line with c# MVC performance, and about 88x faster than Suave's basic server (thanks mostly to Kestral). To create a common functional API layer, Giraffe would have to go back to Async binding but in doing so loose 20% of its speed as it would run into the issues of :

  1. Converting back and forth between Task & Async (additional scheduling)
  2. Wrapping sync values in Async, just to fit in the pipeline (Giraffe never needs to wrap thanks to continuations)

In case anyone is unfamiliar with Giraffe, it's main composable function, comparable to Suave's Webpart is its HttpHandler but the signatures are different:

Suave WebPart (accepts HttpContext) =

type WebPart = HttpContext -> Async<HttpContext option>

Giraffe Httphandler (accepts both a continuation/nextFn & HttpContext)=

type HttpFunc = HttpContext -> Task<HttpContext option>
type HttpHandler = (HttpFunc -> HttpContext) -> Task<HttpContext option> // HttpFunc -> HttpFunc

@mrkaspa I think the idea is to discuss the feasibility of merging Giraffe (that uses ASP.net core) into Suave so that in the end Suave would have an ASP.Net core server option.

@mrkaspa

This comment has been minimized.

Show comment
Hide comment
@mrkaspa

mrkaspa Sep 27, 2017

That would be good to have a solid web library for f# avoiding the ecosystem fragmentation

mrkaspa commented Sep 27, 2017

That would be good to have a solid web library for f# avoiding the ecosystem fragmentation

@sandeepc24

This comment has been minimized.

Show comment
Hide comment
@sandeepc24

sandeepc24 Sep 27, 2017

Merging would make it easier to push F# into organisations reluctant to try F#.

sandeepc24 commented Sep 27, 2017

Merging would make it easier to push F# into organisations reluctant to try F#.

@JonCanning

This comment has been minimized.

Show comment
Hide comment
@JonCanning

JonCanning Sep 27, 2017

Contributor

My thoughts are that they solve different problems. Suave is a standalone framework whereas Giraffe is a set of functional helpers that sit on top of a different framework. What's to merge?

Contributor

JonCanning commented Sep 27, 2017

My thoughts are that they solve different problems. Suave is a standalone framework whereas Giraffe is a set of functional helpers that sit on top of a different framework. What's to merge?

@MattJOlson

This comment has been minimized.

Show comment
Hide comment
@MattJOlson

MattJOlson Sep 27, 2017

IMO one of the best things about Suave its its standalone nature. Giraffe looks great and I can see places where my (C#) org would have an easier time adopting an F# webapp that plugs right into a familiar ASP.NET framework, but equally I've been able to roll out internal tools more easily with Suave because the configuration burden was lower.

MattJOlson commented Sep 27, 2017

IMO one of the best things about Suave its its standalone nature. Giraffe looks great and I can see places where my (C#) org would have an easier time adopting an F# webapp that plugs right into a familiar ASP.NET framework, but equally I've been able to roll out internal tools more easily with Suave because the configuration burden was lower.

@ademar

This comment has been minimized.

Show comment
Hide comment
@ademar

ademar Sep 28, 2017

Hi @dustinmoris

There is nothing to merge. The projects serve different purposes and niches.

Suave is first and foremost a stand alone web server. One of the things that has made Suave successful is the easiness of spawning a web server with minimal ceremony and no dependencies. Suave also runs on Mono, Android and iOS.

I do not care about Kestrel and the ASP.NET stack and have nothing against Giraffe filling that space.

Cheers,

ademar commented Sep 28, 2017

Hi @dustinmoris

There is nothing to merge. The projects serve different purposes and niches.

Suave is first and foremost a stand alone web server. One of the things that has made Suave successful is the easiness of spawning a web server with minimal ceremony and no dependencies. Suave also runs on Mono, Android and iOS.

I do not care about Kestrel and the ASP.NET stack and have nothing against Giraffe filling that space.

Cheers,

@nojaf

This comment has been minimized.

Show comment
Hide comment
@nojaf

nojaf Sep 28, 2017

Contributor

It be nice to have only one defacto F# web framework. The strength of Giraffe is the familiarity with the AspNet stack. Suave really is its own thing, I wouldn't consider merging the two.

Contributor

nojaf commented Sep 28, 2017

It be nice to have only one defacto F# web framework. The strength of Giraffe is the familiarity with the AspNet stack. Suave really is its own thing, I wouldn't consider merging the two.

@forki

This comment has been minimized.

Show comment
Hide comment
@forki

forki Sep 28, 2017

Contributor

@ademar what I'd like to see is a common lib that shares most of the user accessible apis. Like a combinator library that works on both server implementations. Since one is using task and the other one is using async (and we don't have type classes) it may just be the names and two different implementations. I personally think that both projects and especially its users would benefit a lot from a shared documentation and something like an umbrella project. As already discussed both server technologies have some advantages and it would be very good if we could somehow bring these worlds together.

So from my point of view a merge would be really really big win for the ecosystem. But that merge does not mean to be on a code level. I'm hoping we can create an umbrella and share docs + mindset.

Contributor

forki commented Sep 28, 2017

@ademar what I'd like to see is a common lib that shares most of the user accessible apis. Like a combinator library that works on both server implementations. Since one is using task and the other one is using async (and we don't have type classes) it may just be the names and two different implementations. I personally think that both projects and especially its users would benefit a lot from a shared documentation and something like an umbrella project. As already discussed both server technologies have some advantages and it would be very good if we could somehow bring these worlds together.

So from my point of view a merge would be really really big win for the ecosystem. But that merge does not mean to be on a code level. I'm hoping we can create an umbrella and share docs + mindset.

@isaacabraham

This comment has been minimized.

Show comment
Hide comment
@isaacabraham

isaacabraham Sep 28, 2017

It's the programming model that's key for me - things like the >=> operator, CHOOSE and whatnot. In a perfect world (IMHO) we'd have a common library to compose functions into routes in some abstract manner, which is then adapted into either ASP .NET or Suave's web server. There are many benefits to this approach, the biggest IMHO being documentation and ease of adoption - rather than two websites with two approaches to documenting this, two sets of learning material etc., it can all be compressed into one. Less work to maintain for the project owners, easier to learn for new users, and a bigger overall community - to me, a win-win situation. In addition, the set of combinators could (hopefully) grow more quickly and would guarantee consistency as well.

Of course, I'm sure that there will always be things that are unique to Suave or Giraffe - but that can be managed through a set of Suave-specific combinators that are e.g. a separate NuGet package.

isaacabraham commented Sep 28, 2017

It's the programming model that's key for me - things like the >=> operator, CHOOSE and whatnot. In a perfect world (IMHO) we'd have a common library to compose functions into routes in some abstract manner, which is then adapted into either ASP .NET or Suave's web server. There are many benefits to this approach, the biggest IMHO being documentation and ease of adoption - rather than two websites with two approaches to documenting this, two sets of learning material etc., it can all be compressed into one. Less work to maintain for the project owners, easier to learn for new users, and a bigger overall community - to me, a win-win situation. In addition, the set of combinators could (hopefully) grow more quickly and would guarantee consistency as well.

Of course, I'm sure that there will always be things that are unique to Suave or Giraffe - but that can be managed through a set of Suave-specific combinators that are e.g. a separate NuGet package.

@isaacabraham

This comment has been minimized.

Show comment
Hide comment
@isaacabraham

isaacabraham Sep 28, 2017

@forki maybe that's the first step - perhaps a documented set of combinators that follow a consistent convention on some common site. Code-level "sharing" could initially be as simple as just having a consistent approach to namespacing, modules and function names.

isaacabraham commented Sep 28, 2017

@forki maybe that's the first step - perhaps a documented set of combinators that follow a consistent convention on some common site. Code-level "sharing" could initially be as simple as just having a consistent approach to namespacing, modules and function names.

@dustinmoris

This comment has been minimized.

Show comment
Hide comment
@dustinmoris

dustinmoris Sep 28, 2017

Member

Thanks for all the comments so far! I do respect the opinion of the community (hence why I created this issue), but I also respect the opinion of @ademar and if he's happy with the current situation then I'm afraid there's little purpose for me to push any further, as it would make things for me more difficult too.

In terms of shared docs and shared combinators I think it is a noble idea, but my pragmatic side tells me that it would probably add a lot more complication to the ease and speed of development of both frameworks in return of a very small reward, as I really don't think that it's very difficult to pick up the combinators of each framework.

For example, there is already a subtle but significant difference between Suave and Giraffe. If a combinator returns Some ctx in Suave then the next combinator will further process the HttpRequest, whereas in Giraffe this would end the pipeline and finish the request at this point. In Giraffe you'd have to invoke the next handler (similar to middleware) in order to further process the request. These differences already need to be picked up by anyone who wants to use either framework and it's very unlikely to go away.

Personally I see the biggest win through more collaboration by sending each other PRs with features/combinators or other improvements where we think the other framework could benefit from it. I wanted to contribute a lot more back to Suave and I actually started with a small PR not too long ago and I would like to do this more in the future if it is received well. I also want Suave to be great and I'd be happy to send multiple PRs whenever I have time and then let them decide if they like it or not. I wouldn't be uspet if ademar would reject 5 PRs in a row and then only accept one. It needs to make sense for Suave and their vision! :)

Anyways.. these are my two cents, but I'll let this thread go on for a bit longer and see if anyone else has some great ideas/thoughts on this topic or if opinions change.

Member

dustinmoris commented Sep 28, 2017

Thanks for all the comments so far! I do respect the opinion of the community (hence why I created this issue), but I also respect the opinion of @ademar and if he's happy with the current situation then I'm afraid there's little purpose for me to push any further, as it would make things for me more difficult too.

In terms of shared docs and shared combinators I think it is a noble idea, but my pragmatic side tells me that it would probably add a lot more complication to the ease and speed of development of both frameworks in return of a very small reward, as I really don't think that it's very difficult to pick up the combinators of each framework.

For example, there is already a subtle but significant difference between Suave and Giraffe. If a combinator returns Some ctx in Suave then the next combinator will further process the HttpRequest, whereas in Giraffe this would end the pipeline and finish the request at this point. In Giraffe you'd have to invoke the next handler (similar to middleware) in order to further process the request. These differences already need to be picked up by anyone who wants to use either framework and it's very unlikely to go away.

Personally I see the biggest win through more collaboration by sending each other PRs with features/combinators or other improvements where we think the other framework could benefit from it. I wanted to contribute a lot more back to Suave and I actually started with a small PR not too long ago and I would like to do this more in the future if it is received well. I also want Suave to be great and I'd be happy to send multiple PRs whenever I have time and then let them decide if they like it or not. I wouldn't be uspet if ademar would reject 5 PRs in a row and then only accept one. It needs to make sense for Suave and their vision! :)

Anyways.. these are my two cents, but I'll let this thread go on for a bit longer and see if anyone else has some great ideas/thoughts on this topic or if opinions change.

@piaste

This comment has been minimized.

Show comment
Hide comment
@piaste

piaste Oct 1, 2017

@gerardtoconnor

I think a lot of applications still use the simple own server implementation eg Ionide & FSCS, to allow simple micro server instances to be used as app api ... using full dotnet core, due to its heavy caching and pooling would take up a lot of memory in their basic cases, makes sense to keep for these use cases.

This is interesting. Do you have any link on the subject?

@MattJOlson, @ademar

IMO one of the best things about Suave its its standalone nature. Giraffe looks great and I can see places where my (C#) org would have an easier time adopting an F# webapp that plugs right into a familiar ASP.NET framework, but equally I've been able to roll out internal tools more easily with Suave
because the configuration burden was lower.

Suave is first and foremost a stand alone web server. One of the things that has made Suave successful is the easiness of spawning a web server with minimal ceremony and no dependencies.

Isn't ASP.NET Core rather low-ceremony as well? Suave is mono myServer.exe, Core is dotnet run myServer.dll. I think that advantage is much reduced compared to previous ASP.NET implementations.

Suave also runs on Mono, Android and iOS.

This is a very good point. While both can run on Linux, I assume you're currently SOL if you want to run .NET Core on a mobile platform, right?

piaste commented Oct 1, 2017

@gerardtoconnor

I think a lot of applications still use the simple own server implementation eg Ionide & FSCS, to allow simple micro server instances to be used as app api ... using full dotnet core, due to its heavy caching and pooling would take up a lot of memory in their basic cases, makes sense to keep for these use cases.

This is interesting. Do you have any link on the subject?

@MattJOlson, @ademar

IMO one of the best things about Suave its its standalone nature. Giraffe looks great and I can see places where my (C#) org would have an easier time adopting an F# webapp that plugs right into a familiar ASP.NET framework, but equally I've been able to roll out internal tools more easily with Suave
because the configuration burden was lower.

Suave is first and foremost a stand alone web server. One of the things that has made Suave successful is the easiness of spawning a web server with minimal ceremony and no dependencies.

Isn't ASP.NET Core rather low-ceremony as well? Suave is mono myServer.exe, Core is dotnet run myServer.dll. I think that advantage is much reduced compared to previous ASP.NET implementations.

Suave also runs on Mono, Android and iOS.

This is a very good point. While both can run on Linux, I assume you're currently SOL if you want to run .NET Core on a mobile platform, right?

@gerardtoconnor

This comment has been minimized.

Show comment
Hide comment
@gerardtoconnor

gerardtoconnor Oct 2, 2017

Member

@piaste as mentioned in quote, Ionide (link) is the first example that comes to mind but are many more others. Ionide starts a local Suave server api backend that interfaces with command line FSCS, VSCode then works as a JS/Fable webapp that calls the Suave API.

Member

gerardtoconnor commented Oct 2, 2017

@piaste as mentioned in quote, Ionide (link) is the first example that comes to mind but are many more others. Ionide starts a local Suave server api backend that interfaces with command line FSCS, VSCode then works as a JS/Fable webapp that calls the Suave API.

@dustinmoris

This comment has been minimized.

Show comment
Hide comment
@dustinmoris

dustinmoris Oct 29, 2017

Member

Closing as there was no new input for the last 20+ days.

Member

dustinmoris commented Oct 29, 2017

Closing as there was no new input for the last 20+ days.

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