Introdução

Neste tutorial, vamos explorar a criação de APIs RESTful utilizando F# com os frameworks Giraffe e fsharp.webapi. O propósito dessa guia é fornecer uma base sólida para programadores que desejam construir APIs modernas e eficientes usando a linguagem funcional F#. Vamos abordar desde a configuração do ambiente de desenvolvimento até a implementação de testes unitários, fornecendo um ciclo de desenvolvimento completo. Através de exemplos práticos e códigos executáveis, você aprenderá a implementar um servidor de API RESTful, manipulando rotas, requisições e respostas, e integrando com um banco de dados. Não é necessário ter experiência prévia com F#, pois cobrirá todos os conceitos fundamentais necessários para começar a criar suas aplicações Web com esse poderoso framework.

Etapas

  1. Configuração do Ambiente de Desenvolvimento

    Certifique-se de ter o .NET SDK instalado. Você pode verificar a instalação com o comando `dotnet –version`. Caso não o tenha, siga as instruções oficiais no site da Microsoft para instalação do .NET.

    commands
    # Verificar a versão do .NET
    dotnet --version

  2. Criação do Projeto F# com Giraffe

    Utilize o comando dotnet CLI para criar um novo projeto F# com Giraffe. Execute o seguinte comando em seu terminal:

    commands
    dotnet new giraffe -n MinhaApiRestful
    cd MinhaApiRestful

  3. Instalação de Dependências

    Abra o arquivo `MinhaApiRestful.fsproj` e adicione as dependências necessárias para o projeto, como Giraffe e fsharp.webapi. Após isso, execute o comando abaixo no terminal para restaurar as dependências.

    MinhaApiRestful.fsproj
    <Project Sdk="Microsoft.NET.Sdk.Web">
      <PropertyGroup>
        <TargetFramework>net5.0</TargetFramework>
      </PropertyGroup>
      <ItemGroup>
        <PackageReference Include="Giraffe" Version="6.0.0" />
        <PackageReference Include="fsharp.webapi" Version="0.1.0" />
      </ItemGroup>
    </Project>

    commands
    dotnet restore

  4. Configuração da API Giraffe

    Abra o arquivo `Program.fs` e configure o servidor Giraffe para definir as rotas e a lógica para responder às requisições. O código abaixo é um exemplo de configuração de uma rota simples.

    Program.fs
    module Program
    
    open System
    open Giraffe
    open Microsoft.AspNetCore.Hosting
    open Microsoft.Extensions.Hosting
    
    let webApp = 
        choose [
            GET >=> choose [
                route "/" >=> text "Bem-vindo à minha API!"
            ]
        ]
    
    [<EntryPoint>]
    let main _ = 
        Host.CreateDefaultBuilder()
            .ConfigureWebHostDefaults(fun webHost ->
                webHost
                    .UseGiraffe(webApp)
                    .UseUrls("http://localhost:5000")
                    .ConfigureKestrel(fun options ->
                        options.Limits.MaxRequestBodySize <- null
                    )
            )
            .Build()
            .Run()
        0

  5. Criação de um Modelo de Dados

    Defina um modelo de dados para sua API. Neste exemplo, criaremos um tipo de cliente com nome e email. Crie um arquivo `Client.fs` e adicione o seguinte código.

    Client.fs
    type Client = { Id: int; Name: string; Email: string }

  6. Implementação de um Repositório de Dados

    Crie um repositório simples em memória para manipular os dados do cliente. Adicione o código abaixo em um novo arquivo chamado `ClientRepository.fs`.

    ClientRepository.fs
    module ClientRepository
    
    open System
    open System.Collections.Concurrent
    
    let private clients = ConcurrentDictionary<int, Client>()
    
    let addClient client = 
        clients.TryAdd(client.Id, client) |> ignore
    
    let getClientById id = 
        match clients.TryGetValue(id) with
        | true, client -> Some client
        | _ -> None
    
    let getAllClients() = clients |> Seq.map snd

  7. Implementação de Controladores

    Crie um controlador para gerenciar as operações de cliente. Insira o código abaixo em um arquivo `ClientController.fs`.

    ClientController.fs
    module ClientController
    
    open Giraffe
    open ClientRepository
    
    let getClientsHandler : HttpHandler =
        fun next ctx ->
            let clients = getAllClients() |> Seq.toList
            json clients next ctx
    
    let addClientHandler : HttpHandler =
        fun next ctx ->
            Task.Run(fun () ->
                let! client = ctx.BindJsonAsync<Client>()
                addClient client
                text "Cliente adicionado com sucesso!" next ctx
            ) |> Async.StartAsTask

  8. Definindo as Rotas da API

    No seu arquivo `Program.fs`, defina as rotas da API para os endpoints que você deseja expor. Adicione as rotas para os métodos que você criou anteriormente.

    Program.fs
    let webApp = 
        choose [
            GET >=> route "/clients" >=> getClientsHandler
            POST >=> route "/clients" >=> addClientHandler
        ]

  9. Teste da API com Ferramentas Externas

    Para testar a API, você pode usar o Postman ou o cURL. Execute a aplicação e faça as requisições conforme os exemplos abaixo.

    commands
    # Executar a aplicação
    dotnet run
    # Obter todos os clientes
    curl -X GET http://localhost:5000/clients
    # Adicionar um novo cliente
    curl -X POST -H "Content-Type: application/json" -d '{"Id": 1, "Name": "John Doe", "Email": "john@example.com"}' http://localhost:5000/clients

  10. Implementação de Testes Unitários

    Crie testes unitários para validar a lógica de seus manipuladores. Utilize uma estrutura como Expecto para isso. Crie um arquivo `ClientControllerTests.fs`.

    ClientControllerTests.fs
    module ClientControllerTests
    
    open Expecto
    open ClientController
    
    [<Tests>]
    let tests = testList "Client Controller Tests" [
        test "Testar adição de cliente" {
            // Implementar teste para verificar se um cliente é adicionado corretamente.
        }
    ]

Conclusão

Neste tutorial, você aprendeu a criar uma API RESTful com F# utilizando Giraffe e fsharp.webapi. Passamos por todas as etapas, incluindo configuração do ambiente, implementação de modelos, repositórios, controladores, e até mesmo testes unitários. Com este conhecimento, você está preparado para desenvolver aplicações mais complexas e integrar mais funcionalidades à sua API. A programação funcional com F# oferece um novo paradigma que pode melhorar a eficiência e legibilidade do seu código, facilitando o desenvolvimento de soluções robustas.

Hashtags

#F# #Giraffe #APIs #RESTful #fsharp.webapi #DesenvolvimentoDeSoftware