Introduction To Suave With F#

In this article, we will see how to construct a simple web application with the F# language and the Suave Web Server on Visual Studio Code.

Suave

Suave is a simple Web Server that can run web applications. It runs on Windows, OS X, and Linux and F# is the language used on it.

F# is a functional language created by Microsoft in 2002.

F# combined with Suave enables a set of combinators to manipulate the route flows and task composition. We can build a web application very easily and quickly with the F# syntax and Suave lightweight.

Suave with F#

Install the tools

Let’s begin by installing all the tools to start our application. We will use Visual Studio Code, a free and open source editor where we can add extensions for building applications.

I love Visual Studio Code’s modularity because we can transform it into a very powerful work tool. You can download it here for free. The installation is very fast and simple. Once installed, open it.

We will now install F# tools in Visual Studio Code: on the left side, there is a vertical bar with five buttons.

Suave with F#

Respectively

  • A file and solution explorer
  • A search section
  • A source control (for tool like Git)
  • A debugger
  • And an extension manager

For installing F#, we will go to the Extension Manager. Just click on the last icon with your mouse.

Suave with F#

Search for three extensions and click "Install" on them.

  • Ionide F#: for the F# language support
  • Ionide Paket: a packet managers like NuGet but for the F# project.
  • Ionide FAKE: a tool for automate build like a Makefile but for F#.

After installations, restart Visual Studio Code. Now, we are ready to start.

Ensure to follow installation details so that F# can run properly on your computer.

Create a new F# suave project

Ionide will help us a lot by providing some start templates for create application. Like Visual Studio, you can generate a start project for a console app, library, or Suave.

In the first place, create a repository for you project on your computer. I will name it HelloSuave, for example. Then, open this repository with Visual Studio Code (menu File > Open repository).

Suave with F#

Now, to create a project, we need to access the command pallet (Ctrl+Shift+P on Windows, ⌘+Shift+P on macOS, Ctrl+Shift+P on Linux) and type the following.

Suave with F#

Select and press Enter on F#: New Project. Then, in the list of templates, select F# Suave project and press Enter again. When Visual Studio asks you to choose a directory, just leave the field empty and press Enter. Name the project as HelloSuave or whatever you prefer.

After a short time, all the files needed are generated.

Suave with F#

All the project code is in HelloSuave (under –no-prompt) subdirectory. There are also two files which will interest us: paket.dependencies and build.fsx.

In the dependencies PAKET file, we get all packages needed to run a Suave application.

Suave with F#

We actually have reference to FAKE, the automation build tool, F# Core, and Suave, all referenced in the NuGet source.

The build.fsx file act as a Makefile in F#, you can define some build action.

Suave with F#

That will generate or install tools, or clean a project directory.

Now, let’s focus on Suave. We have actually one source file very simple for our web application - HelloSuave.fs with the following lines of code.

open Suave                 // always open suave
open Suave.Successful      // for OK-result
open Suave.Web             // for config
startWebServer defaultConfig (OK "Hello World!")

It simply starts the web server with default configuration (port 8083) and registers a WebPart OK “Hello World!”. A WebPart is basically a function that will be executed on the server. OK means the response status is 200 that means the request returns a good result.

Build and run the application 

In Visual Studio Code, go to Menu Display > integrated Terminal. That will open a terminal window in your work directory.

Suave with F#

On Windows, just type .\build.cmd and press Enter and on OS X and Linux, type ./build.sh. The build will take some time for downloading the packages and build the solution by following the steps in the build.fsx with FAKE tool.

Suave with F#

If all is fine. We can now execute our server. The executable is located in –no-prompt\HelloSuave\bin\Debug\net461\HelloSuave.exe. Execute it via the terminal.

Suave with F#

Now, our web application is running on the server at this address: 127.0.0.1:8080. Open a Web browser and enter the URL in the URL text field.

Suave with F#

Perfect! It works fine.

Explain the code 

There is actually only one line of code, that is a function call to startWebServer. Let’s look at its signature.

val startWebServer: config : SuaveConfig ->webpart: WebPart -> unit

That means startWebServer is a function that takes two objects in parameters, one of type SuaveConfig and the second of type WebPart, the function return a unit value, in F# unit indicates the absence of a specific value.

As a first parameter, we pass it defaultConfig - this is a value that indicates the default configuration of the server. It is enough for our example, we don’t need more.

The most interesting part is the second parameter of type WebPart. A WebPart is represented by the following function signature:

HttpContext -> Async<HttpContext option>

HttpContext contains the information for the request and the response. It returns a promise of type HttpContext option. Option is a specific type in F# that indicates something can have or not a value, it is different from null in C#.

Value of type Option can take two values: Some X or None. When Some X is returned, this ensures there is a non-null value. That’s why we say there is no null values in F#.

Create a route 

A route is basically a URL path. An application can have multiple paths for different pages or requests.

Let’s create a new webpart that will define routes for our application,

  1. let webPart =  
  2.     choose [  
  3.         path "/" >=> (OK "Home")  
  4.         path "/about" >=> (OK "About")  
  5.     ]  

We use the choose function that enables to create some routes with path, another function that takes a string and returns a WebPart.

Don’t forget to add the following namespaces.

  • open Suave.Filters
  • open Suave.Operators

An interesting point is the >=> operator. It comes from Suave library (Suave.operators namespace) and composes two webparts in one, by evaluating the webpart on the left and applying it on the webpart on the right only if the web part of the left returns Option Some (have a value non-null).

Change a last thing: we have to indicate to startWebServer the webpart we added, so change the startWebServer call with our webpart.

startWebServer defaultConfig webPart

Let us rebuild our application, then try to navigate from the URL field in the browser to the following address.

  • http://127.0.0.1:8080/
  • http://127.0.0.1:8080/about

You should see the content we have given in the string on the webparts from the routes.

Suave with F#

Good!

Displaying Views

Suave brings its own manner to generate the Views (HTML code).

First, we need to add a package so that the HTML extensions work in our project. In the paket.dependencies, add the following line in the file:

nuget Suave.Experimental 2.2.1

And make sure to add Suave.Experimental to the paket.references in our project (under FSharp.Core and Suave). Then, let’s run the paket install command,

Suave with F#

Paket is a program located in .paket subfolder.

Add a new F# file in the solution called View (for example). Ensure that the file is added to the project by pressing Ctrl + Shift + P and start type F# and select “F#: add the current file to the project”.

The last thing is to check that the View.fs file is compiled before HelloSuave.fs (the order of files is very important in F#). Open HelloSuave.fsproj and check View.fs is before HelloSuave.fs. It is very important that the View.fs file comes before HelloSuave.fs. Then, write the following code.

  1. module View  
  2. open Suave.Html  
  3. let index = html[][  
  4.     head[][  
  5.         title[]  
  6.         "Web Application F# CSCorner"  
  7.     ]  
  8.     body[][  
  9.         div["id""header"][  
  10.             tag "h1" [][  
  11.                 a "/" [][Text "F# Suave Introduction"]  
  12.             ]  
  13.         ]  
  14.         div["id""footer"][  
  15.             Text "Share the love with "  
  16.             a "http://fsharp.org" [][Text "F#"]  
  17.             Text " and "  
  18.             a "http://suave.io" [][Text "Suave.io"]  
  19.         ]  
  20.     ]  
  21. ] | > htmlToString  

We can see that we generated HTML from functions that takes array or strings to build the HTML code. The htmlToString transforms the object model generated by HTML function into a string corresponding to a valid HTML document. Don’t forget to open the namespace Suave.html.

We can see that all functions that composed the HTML document are related to HTML tags such as body, div, a. It is very intuitive and elegant way to generate the HTML code.

The last step is to configure the routes for redirecting to our View.

  1. let webPart =  
  2.     choose [  
  3.         path "/" >=> (OK View.index)  
  4.         path "/about" >=> (OK "About")  
  5.     ] 

And now, the result -

Suave with F#

Conclusion 

This is the end of this basic introduction to Suave.io with F#. Don’t hesitate to comment if you have questions.


Similar Articles