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.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>
-
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
-
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
-
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 parametersa
andb
.
-
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: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.
- 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