O Giraffe é um micro web framework em F# para construir aplicações web. Ele é baseado no ASP.NET Core, fornecendo uma API F# ao framework web. O Giraffe é direcionado a desenvolvedores que querem construir aplicações web em F# e querem manter acesso aos recursos do ASP.NET Core e seu ecossistema.
A sintaxe do Giraffe é similar à do Suave, um outro framework web popular também em F#. A semelhança levantou questões sobre a possibilidade dos dois frameworks deveriam ser unificados ou distribuídos em um mesmo conjunto de APIs. O criador do Giraffe explica porque ele não acredita que fazer um merge traria muito valor:
Uma das principais diferenças entre o GIraffe e o Suave é que a visão fundamental do Giraffe, geralmente definida, é para fortemente se integrar com o ASP.NET Core. O Giraffe nasceu para atender o nicho de desenvolvedores funcionais de .NET que querem construir aplicações web funcionais em ASP.NET Core. O Giraffe tenta preencher esse nicho específico fornecendo uma fina camada sobre o ASP.NET Core, mas mantendo os blocos de construção principais do ASP.NET Core vivos (injeção de dependência, HttpRequest, HttpResponse, Config, etc). Isso habilita desenvolvedores de F# a usar muito do ecossistema ASP.NET Core já existente (e que está porvir).
O principal bloco de construção do Giraffe é o HttpHandler. Um HttpHandler é um fluxo de funções, semelhante à composição do ASP.NET Core pelo IApplicationBuilder. O manipulador pode continuar o fluxo processado chamando o próximo manipulador.
type HttpHandler = HttpFunc -> HttpContext -> HttpFuncResult
O Giraffe utiliza uma abordagem de combinação, em que HttpHandlers são combinados para criar níveis mais altos de abstração e por fim criar uma aplicação.
let webApp = choose [ route “/foo” >=> text “Foo” route “/bar” >=> text “Bar” ] type Startup() = member __.Configure (app : IApplicationBuilder) (env : IHostingEnvironment) (loggerFactory : ILoggerFactory) = app.UseGiraffe webApp
O Giraffe utiliza a Task do .NET ao invés de fluxos async, pois as duas implementações são diferentes e requerem conversão de um para o outro. O Giraffe minimiza conversões de forma a reduzir sobrecarga.
let personHandler = fun (next : HttpFunc) (ctx : HttpContext) -> task { let! person = ctx.BindModel() return! json person next ctx }
Exemplos de aplicação disponíveis no GitHub.