How to have more fun with a SAFE Stack

2020-03-17 0 By Nordes

While watching some video from London NDC’20 on YouTube, some older video appeared within the suggestion box and I clicked on it due to my interest in the matter. Basically, it was a video talking about how to create a Office 365 Excel like F# |> Elmish |> React app. It’s quite interesting and the guy build something incredible in only 1 hour. (Link here)

By watching that video I started to search what he used and then stumbled on the official fable elmish repository, but also I found out an another one which is more to my liking and it was SAFE Stack (SAFE stands for Saturn Azure Fable and Elmish). A nice article have been written not long ago by Isaac Abhrams (MSDN Link), so I won’t try to repeat what he already wrote.

In this article, we will simply explore how to create your first application.

Why is it so interesting

Basically, if we use the SAFE Stack, everything is more or less working together. You write your back-end in F#, your front-end in F# and then you can share domain objects and basic functions between the two since all is compiled (or transpiled depending where you look at). If you run all within VS Code, it’s going to be a nice experience since you can save in back or front and then see the new results on the interface (back-end needs a page refresh in such a case or a new call to the server).

When putting breakpoints in the F# file, you can debug your front or backend directly. Also, if you know React JS and it’s plugin in Chrome, you know that you have a time machine for your front-end. It’s also working out of the box, so it’s great to debug or receive an “how to reproduce” script.

Requirements

  • NodeJs
  • Yarn
  • Dotnet Core 3.1
  • Crome with Redux extension (Didn’t work with Brave Browser due to some linking from VS Code)

More details at https://safe-stack.github.io/docs/quickstart/

Let’s install SAFE Stack

We’re in March 2020 and it’s .Net Core 3.1 era.

Add a new template to your dotnet new

This will allow you to scaffold template project. The project being quite active, I suggest you to update once in a while by retyping the same command. It will download the latest version while re-installing. (It’s based on a NuGet template package which you can follow).

dotnet new -i SAFE.Template

Create a new folder and then scaffold a first app

Details on command line arguments at https://safe-stack.github.io/docs/template-overview/

dotnet new SAFE --layout fulma-cover --deploy docker

Restore the whole app (takes a bit of time)

dotnet tool restore

Run without VS Code (No nice debugging experience)

Use the following to see if all is working as expected (Takes time on the first launch since it downloads everything).

dotnet fake build --target run

Run within VS Code (Integrated and nice experience)

Open VS Code in the current folder code .. If the extension required to run are not installed it will pop-up the following message. Simply agree

Once installed, if not already go on the debug icon on the left menu bar and look at the targets:

Click on Debug SAFE App. This will start both front-end and back-end server and watch/attach process in VS Code. This will allow to do live debug. After you click and wait, you should have 2 process attached

If you look at your source code from the F# view (default it after you have installed the plugin and opened a folder with FS files). You will see that you have only a few files, while in reality you have many. Simply go in the folder view to see everything. You will also see there’s a shared folder with a file. That file is shared through the FSProj file.

Default view after starting the application

Application created, let’s explore quickly the files

Front-end

All the front-end is build using react/redux. Since it’s the case and it’s quite nice, you can use the time machine to play around.

The code to generate the UX is something that looks like bellow:

let containerBox (model : Model) (dispatch : Msg -> unit) =
    Box.box' [ ]
        [ Field.div [ Field.IsGrouped ]
            [ Control.p [ Control.IsExpanded ]
                [ Input.text
                    [ Input.Disabled true
                      Input.Value (show model) ] ]
              Control.p [ ]
                [ Button.a
                    [ Button.Color IsPrimary
                      Button.OnClick (fun _ -> dispatch Increment) ]
                    [ str "+" ] ]
              Control.p [ ]
                [ Button.a
                    [ Button.Color IsPrimary
                      Button.OnClick (fun _ -> dispatch Decrement) ]
                    [ str "-" ] ] ] ]

Most of the UX is created using Fulma functions (Control.p, Field.div, etc.). In case you would like to have a line break, you could add a line with br []. It’s not because it’s using most likely Fulma that you cannot use the Fable.React.Standard html controls.

The first [] are for the style (class and stuff like that) and the second [] is the content.

The default project put all within one file, but nothing does not allow you to split across multiple file. Even the tutorial SAFE-Dojo is built using a bit more separation of concerns.

Back-end

Like the front-end, I would have loved to have a better separation within the template scaffolding. Right now, only one file is created and it’s up to you to know what to do.

Since the back-end is built around Saturn and Giraffe, you can see at the doc to understand more how to split your files (Which I highly recommend).

Otherwise, for the back-end, it’s the usual. You use your code and favorite libraries. Don’t forget that you can share some logic and types between your back and front.

Next step

I will try to come back on this, but, it will be about moving the file around and going a bit deeper with a bigger scenario. At the moment, the samples on the website are not all up to date and you might experience some issue by running them. That being said, enjoy playing around until the next post.

Thank you for reading!