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
-
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 -
Add Giraffe package: Add the Giraffe package to your project:
dotnet add package Giraffe -
Modify the project file: Open the
GiraffeApp.fsprojfile 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> -
Create the application entry point: Replace the content of
Program.fswith 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 -
Run the application: Execute the following command to run your Giraffe application:
dotnet runOpen your browser and navigate to
http://localhost:5000to 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
-
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 parametersaandb.
-
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 -
Testing:
- Navigate to
http://localhost:5000to see the welcome message. - Navigate to
http://localhost:5000/hello/Johnto see the personalized greeting. - Navigate to
http://localhost:5000/add?a=5&b=3to see the sum of 5 and 3.
- Navigate to
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.
F# Programming Course
Module 1: Introduction to F#
Module 2: Core Concepts
- Data Types and Variables
- Functions and Immutability
- Pattern Matching
- Collections: Lists, Arrays, and Sequences
Module 3: Functional Programming
Module 4: Advanced Data Structures
Module 5: Object-Oriented Programming in F#
- Classes and Objects
- Inheritance and Interfaces
- Mixing Functional and Object-Oriented Programming
- Modules and Namespaces
Module 6: Asynchronous and Parallel Programming
Module 7: Data Access and Manipulation
Module 8: Testing and Debugging
- Unit Testing with NUnit
- Property-Based Testing with FsCheck
- Debugging Techniques
- Performance Profiling
