Introduction

Giraffe is a functional web framework for building web applications in F#. It leverages ASP.NET Core's powerful features while providing a functional programming approach. In this module, we will cover the basics of setting up a Giraffe project, creating routes, handling requests, and rendering responses.

Setting Up a Giraffe Project

Prerequisites

Before we start, ensure you have the following installed:

  • .NET SDK (version 5.0 or later)
  • An IDE or text editor (e.g., Visual Studio, Visual Studio Code)

Creating a New Giraffe Project

  1. Create a new project: Open your terminal and run the following command to create a new console application:

    dotnet new console -n GiraffeApp
    cd GiraffeApp
    
  2. Add Giraffe package: Add the Giraffe package to your project:

    dotnet add package Giraffe
    
  3. Modify the project file: Open the GiraffeApp.fsproj file and ensure it includes the Giraffe package reference:

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net5.0</TargetFramework>
      </PropertyGroup>
      <ItemGroup>
        <PackageReference Include="Giraffe" Version="5.0.0" />
      </ItemGroup>
    </Project>
    
  4. Create the application entry point: Replace the content of Program.fs with the following code:

    open System
    open Microsoft.AspNetCore.Builder
    open Microsoft.AspNetCore.Hosting
    open Microsoft.Extensions.DependencyInjection
    open Microsoft.Extensions.Hosting
    open Giraffe
    
    let webApp =
        choose [
            route "/" >=> text "Hello, World from Giraffe!"
        ]
    
    let configureApp (app: IApplicationBuilder) =
        app.UseGiraffe webApp
    
    let configureServices (services: IServiceCollection) =
        services.AddGiraffe() |> ignore
    
    [<EntryPoint>]
    let main args =
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(fun webHostBuilder ->
                webHostBuilder
                    .Configure(configureApp)
                    .ConfigureServices(configureServices)
                    |> ignore)
            .Build()
            .Run()
        0
    
  5. Run the application: Execute the following command to run your Giraffe application:

    dotnet run
    

    Open your browser and navigate to http://localhost:5000 to see "Hello, World from Giraffe!".

Creating Routes

Basic Routing

Giraffe uses a functional approach to define routes. The choose function allows you to specify multiple routes. Here’s an example of adding more routes:

let webApp =
    choose [
        route "/" >=> text "Hello, World from Giraffe!"
        route "/about" >=> text "About Page"
        route "/contact" >=> text "Contact Page"
    ]

Handling Parameters

You can handle route parameters using the routef function. Here’s an example:

let webApp =
    choose [
        route "/" >=> text "Hello, World from Giraffe!"
        routef "/hello/%s" (fun name -> text (sprintf "Hello, %s!" name))
    ]

Navigating to http://localhost:5000/hello/John will display "Hello, John!".

Handling Requests and Responses

Reading Query Parameters

You can read query parameters using the query function. Here’s an example:

let webApp =
    choose [
        route "/" >=> text "Hello, World from Giraffe!"
        route "/greet" >=> fun next ctx ->
            let name = ctx.TryGetQueryStringValue "name" |> Option.defaultValue "Guest"
            text (sprintf "Hello, %s!" name) next ctx
    ]

Navigating to http://localhost:5000/greet?name=John will display "Hello, John!".

Handling JSON

Giraffe makes it easy to handle JSON. Here’s an example of returning a JSON response:

type Person = {
    Name: string
    Age: int
}

let webApp =
    choose [
        route "/" >=> text "Hello, World from Giraffe!"
        route "/person" >=> json { Name = "John"; Age = 30 }
    ]

Navigating to http://localhost:5000/person will return a JSON response with the person object.

Practical Exercise

Exercise: Create a Simple API

  1. Objective: Create a simple API with the following endpoints:

    • GET /: Returns a welcome message.
    • GET /hello/{name}: Returns a personalized greeting.
    • GET /add?a={a}&b={b}: Returns the sum of two query parameters a and b.
  2. Solution:

    let webApp =
        choose [
            route "/" >=> text "Welcome to the Giraffe API!"
            routef "/hello/%s" (fun name -> text (sprintf "Hello, %s!" name))
            route "/add" >=> fun next ctx ->
                let a = ctx.TryGetQueryStringValue "a" |> Option.map int |> Option.defaultValue 0
                let b = ctx.TryGetQueryStringValue "b" |> Option.map int |> Option.defaultValue 0
                text (sprintf "Sum: %d" (a + b)) next ctx
        ]
    
    let configureApp (app: IApplicationBuilder) =
        app.UseGiraffe webApp
    
    let configureServices (services: IServiceCollection) =
        services.AddGiraffe() |> ignore
    
    [<EntryPoint>]
    let main args =
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(fun webHostBuilder ->
                webHostBuilder
                    .Configure(configureApp)
                    .ConfigureServices(configureServices)
                    |> ignore)
            .Build()
            .Run()
        0
    
  3. Testing:

    • Navigate to http://localhost:5000 to see the welcome message.
    • Navigate to http://localhost:5000/hello/John to see the personalized greeting.
    • Navigate to http://localhost:5000/add?a=5&b=3 to see the sum of 5 and 3.

Conclusion

In this module, we covered the basics of setting up a Giraffe project, creating routes, handling requests, and rendering responses. You should now have a good understanding of how to build simple web applications using Giraffe. In the next module, we will explore creating desktop applications with Avalonia.

© Copyright 2024. All rights reserved