I was frustrated with the verbosity of ASP.NET Core, especially as an F# user. Don’t get me wrong, it is insanely powerful, performant and customisable web framework. And it is also one of the most USER-UNFRIENDLY things I have ever encountered in the web development.
Therefore, I decided to wrap it in some helper functions to make it as pleasant to work with for the new F# web developers as possible. And ... I’ve got somewhat carried away. This is the true origin of this project.
Before F# I was primarily into the Python, and I had really good experience with Django. I wanted to make my helper look more like Django but more I wrote, more it resembled Flask instead.
I have recently open sourced it under the MIT license on GitHub. I hope this will help with making other web developers more interested in seemingly niche language of F#.
I use it for a side project (some SPA app) I work on over the weekends. Therefore, I frequently change and update it as I encounter more missing things or parts that do not please me.
So, all the feedback is welcome! I am especially interested if you find the framework API intuitive enough for non-F# folks.
Wrapping ASP.NET Core to be easier and more idiomatic with F# seems to be a common domain. Out of curiosity, did you look at any existing projects? If so, what was lacking from them that made you decide to write WebFrame?
Since F# is typed, have a look at FastApi in Python. It's a better inspiration than flask: it uses dep injection with typing to configure your endpoints. It's very flexible, infinity composable, and such a nice experience.
Django's API is now clearly dated. I still use it massively though, because it's insanely productive for CRUD apps, which are 99% of my client requests.
They made some hard choices about the auth and db layer, and they are imperfect, but when left to do the choice myself in other frameworks, I often miss Django. You really value all it gives you once you've lost it.
Thank you for mentioning FastAPI. Looks awesome. Recently I started using Flask, as Django feels like too much overhead for smaller projects. FastAPI looks like a good alternative to Flask.
> Django feels like too much overhead for smaller projects
It depends. My advice is always: stick to django no matter what, unless you are a seasoned web devs. I've seen too many flask projects with terrible architecture decisions and security holes because flask assumes (by nature) you can take those decisions.
Those decisions are not easy to take. They require a deep knowledge of the field.
So yes, one may chose flask or fast api as a lighter alternative, provided they know very well what they are doing, or that the consequences of not knowing are small. The later is not always simple to evaluate however, especially if you are not experienced. You don't know what you don't know after all.
If somebody doesn't know if they are an experienced web dev, or the consequences of their choices, they should use Django.
It will save them from SQL injection, XSS, Cross request forgery and click hijacking. It will provide an pluggable auth backend should you need it later. It will force you to put some parts of your code in separate sillows. This is a good thing for most people.
Frankly if you go with the most popular extensions: Flask-SQLAlchemy, Flask-Login and Flask-Admin you will have more or less all the features of Django with a nicer API, better documentation and more flexibility
I've been using all of them, and no, not at all. Flask-admin is a far cry from the django admin. It's also buggy sometimes.
Flask-SQLalchemy is not well integrated at all. E.G: try to play with it in the shell, the session management is annoying as hell.
As of flak-login, it doesn't have a tenth of the
Also you forgot: csrf handling, i18n, xss, click hijacking, cache backends, and so on. That's again, more plugins you have to select.
And that's a lot to configure, learn doc, then upgrade when the times come, on top of that.
All of them will, obviously, not be compatible with SQLA 2 next year, because the projects are not a whole, so it's going to be even more fun on the months to come.
This is a good summary. Sometimes I too forget how much stuff Django provides out of the box for free. But now it is an old and boring tech, apparently. Oh well.
agree it depends, and I haven't looked at Django for years - so can't comment on it.
However, I have been using FastAPI with Jinja2 & htmx to create web APIs and UIs for some of our services. Individually, they're great; collectively they're a joy. I'm no front end dev, but even I can put together functional, decent-looking apps in a few hundred lines of code. They bare comparison to angular apps that can easily be an order of magnitude more code.
I just wanted to mention that I considered FastApi but the amount of reflection and magic required to go this route was a bit too much to my liking in F#. Just a personal preference.
I mostly agree with you on Django though. But as you said - most apps are CRUD apps.
You don't have to use asp.net directly in F# - there's been a long-standing library wrapping it in a more functional aesthetic with Giraffe: https://github.com/giraffe-fsharp/Giraffe
Not to discourage you or anything - always good to see alternatives. Personally, for FP web programming, the closer to the "your server as a function" ideal the better - so I'd prefer Giraffe in this case, for things like the router being an HttpHandler instead of being a property on the app instance. It's just way more intuitive from an FP standpoint and produces neater, more self-contained code, IMO.
> Every time I tried to write something quickly, I often had to choose between a heavily functional programming oriented frameworks or extremely tedious ASP.NET Core.
Agree. dev experience is missing in dotnet IMO. I had the exact same sentiment last year. made https://wiz.run/
I hated going through all the microsoft dotnet docs. Wanted something like this: https://wiz.run/api/
As I recall, Suave is on its way out, and was replaced by Saturn. Saturn is built on Giraffe.
I found Saturn to be incredibly confusing because you need to understand both it and Giraffe to be able to use it.
I used Giraffe for a while, but I still needed to understand the ASP.NET middleware approach, which didn't match Giraffe's.
Also, ASP.NET has a new endpoint based routing framework which is supposed to be very fast. Giraffe has started to adopt that, but I found most of the docs refer to the old way of doing things. So although I'm using it a little bit in the code above, I found it easier to just use ASP.NET directly in most cases.
One of the issues I have with Giraffe is that it gives you too many ways to deal with routing while also asking to use custom operators. And yet I cannot get a list of all defined routes.
Honestly, I do not find their goal of being a functional interface to ASP.NET Core sufficiently compelling. Maybe they should be a bit more specific?
This is fantastic. I prototype, and the last thing I want to do is set up and deal with all the nonsense when I need only usually need a few calls to a server to prove out the concept.
>"Don’t get me wrong, it is insanely powerful, performant and customisable web framework. And it is also one of the most USER-UNFRIENDLY things I have ever encountered"
That is a Microsoft's trademark. They produce powerful and very complex APIs. Historically for native apps it was Borland / now Embarcadero would wrap those in still powerful but very user friendly libs / components for Delphi. Not sure what is available for .NET as I am not using the framework.
Totally missing the point. A good web framework lets you get running with a few lines but then allows you to add custom logic with minimal incidental complexity.
I think you're missing the point. It's not how many lines of code it takes. You have to think a bit harder what the desirable properties are. Minimizing complexity is nice, great start. What does that mean? It's certainly not one of the "guiding principles" of this library. It's focusing on, among other things,
- "least amount of code"
- and "a beautiful code"
shrug
You minimize complexity by defining primitive expressions, means of combination, and means of abstraction [1]. Sound familiar?
Therefore, I decided to wrap it in some helper functions to make it as pleasant to work with for the new F# web developers as possible. And ... I’ve got somewhat carried away. This is the true origin of this project.
Before F# I was primarily into the Python, and I had really good experience with Django. I wanted to make my helper look more like Django but more I wrote, more it resembled Flask instead.
I have recently open sourced it under the MIT license on GitHub. I hope this will help with making other web developers more interested in seemingly niche language of F#.
I use it for a side project (some SPA app) I work on over the weekends. Therefore, I frequently change and update it as I encounter more missing things or parts that do not please me.
So, all the feedback is welcome! I am especially interested if you find the framework API intuitive enough for non-F# folks.
Thanks for your time!