F# is a community driven Functional-First programming language. It’s a multi-paradigm language and interops nicely with C#, but provides a lot of the functional features that make working with it great!
Lately I’ve spent some time learning F# and through F# discovered Suave:
Suave is a simple web development F# library providing a lightweight web server and a set of combinators to manipulate route flow and task composition.
As stated, Suave is a web framework that can be used to create apis. When I was researching Suave I didn’t find a great article documenting all the basic CRUD actions that should be used in a REST API.
This is my attempt to pass along the knowledge I had to piece together over several internet resources. This is not an end to end app, it just documents how to use Suave to setup the necessary routes needed for a simple CRUD app.
All code will be located on a github repo. One of my friends introduced me to Suave . Some of the things he did on his personal project definitely helped me get started in Suave. He's also further down the F# rabbit hole, so check out his project if you're interested.
This article isn’t an introduction to F#. If you’re never encountered the language before, some of the examples here might seem a bit different.
If so, welcome to functional programming languages. My short time learning F# has been quite an eye opening experience.
Throughout my professional life I’ve used both Java and C#. But I incorrectly assumed that best practices I learned for Java and C# were overall programming best practices. When in reality they were best practices for an object oriented language.
Functional languages have a very different way of looking at the world. When you start learning a functional language everything is new and the terms can be intimidating.
Some people get scared off by that fact, but I think it’s worth the time to embrace and learn a new paradigm. That will really only benefit you in the long run.
If you’re new to functional and F# and want to get started, here is a hour long conference talk called Functional Design Patterns by Scott Wlaschin. Scott also blogs at fsharpforfunandprofit.com which is a great resource when you’re getting started.
With that short functional evangelism message behind us, lets dive in.
Open up your IDE of choice, I’m using Visual Studio, and create an F# Console App. Use whatever name you prefer, and after creating you should see something similar to the following in your IDE.
Next we’re going to be adding our dependencies. We’ll need to add Suave and Newtonsoft.Json to our project. Right click on “Dependencies” => “Manage Nuget Packages”, then searching for the two nuget packages and installing them.
Modify the Program.fs to be the following to create your first route.
Running that project should open up a console that says it launched on 127.0.0.1:8080. If that’s the case for you, you can point your web browser to http://localhost:8080/ and you should see your “Hello World” message.
I’m also including a postman collection for all routes contained in this example, which is also located on the github repo.
With that simple example out of the way. Lets demo a full CRUD architecture for an answer entity.
So, I could talk a lot more about the four different routes, Create, Read, Update and Delete, or I could just show you the code. So here’s how I would accomplish setting up routes in Suave for all four actions.
You can use the Postman collection to play around with each route.
You’ll notice that I have two types, one for new answers and one for answers that already exist.
You’ll see extensive use of the F# forward pipe operator, “|>”. It’s shorthand for “get the result of the previous line and pass it into the function on this line”.
Those two examples perform the same work, but using the forward pipe operator is much more concise and I think is easier to read.
If you need to read variables from the path, like I do in the Get answer and Delete answer routes. You’ll need to use pathScan instead of path when defining the route.
Suave does enforce the data types, so if I attempted to pass a string instead of an int Suave wouldn’t be able to find that route because I’m limiting these routes to be an int.
And lastly I’m a huge fan of how succinct F# is. Once you get used to reading and writing F#, everything can usually be expressed in minimal characters. Writing this in C# would be at least twice as many lines of code, probably more.
I enjoyed learning Suave and I hope this article helps you get started faster than I was able to. At the moment I’m really enjoying F# and all it’s functional goodness. Stay tuned for future posts on F# and general dotnet programming!
I’m Morgan Kenyon. I’m a .NET developer working in the DFW area. I find both C# and F# great languages backed by a great ecosystem. I love solving problems and want to continue talking about the tech I use. If you found this article helpful or thought provoking leave a comment and lets connect over LinkedIn!