Introdução

Neste tutorial, você irá aprender a criar uma API RESTful da maneira mais prática e eficiente utilizando a linguagem Haskell e a biblioteca Servant. A Servant é uma das bibliotecas mais robustas para a criação de APIs em Haskell, permitindo que você descreva suas rotas e tipos de forma declarativa. Este guia é voltado para iniciantes, e abordaremos desde a configuração do ambiente de desenvolvimento com Stack até a implementação de uma API básica. A proposta é que, ao final, você esteja confortável em criar suas próprias APIs em Haskell, conhecendo as boas práticas para organização e tipo seguro das rotas e dados.

Etapas

  1. Configuração do Ambiente de Desenvolvimento

    Primeiramente, você precisa instalar o Stack, uma ferramenta de construção que gerencia pacotes Haskell. Você pode baixar o instalador correspondente ao seu sistema operacional no site oficial do Stack. Após a instalação, verifique se tudo está funcionando corretamente.

    commands
    # Verifique a instalação do Stack
    stack --version

  2. Criação do Projeto Haskell

    Crie um novo projeto Haskell usando o Stack, onde nosso projeto será chamado de ‘api-restful’. Use o comando abaixo para gerar a estrutura básica do projeto.

    commands
    stack new api-restful
    cd api-restful

  3. Adicionando Dependências

    Abra o arquivo `package.yaml` gerado pelo Stack e adicione as bibliotecas necessárias para o Servant. Nesse exemplo, vamos utilizar `servant` e `servant-server` para criar nossa API.

    package.yaml
    dependencies:
      - base >= 4.7 && < 5
      - servant
      - servant-server
      - wai
      - wai-extra
      - text
      - http-types

  4. Definindo a API com Servant

    Crie um novo arquivo chamado `Api.hs` no diretório `src/` e defina a sua API. Neste exemplo, vamos criar um endpoint para um recurso chamado ‘produtos’.

    Api.hs
    module Api where
    
    import Servant
    
    type API = "produtos" :> Get '[JSON] [Produto]
             :<|> "produtos" :> Capture "id" Int :> Get '[JSON] Produto
    
    data Produto = Produto { id :: Int, nome :: String, preco :: Double }
      deriving (Eq, Show, Generic)
    
    instance ToJSON Produto
    instance FromJSON Produto

  5. Implementação do Servidor

    Agora, vamos implementar o servidor que irá fornecer as rotas definidas na nossa API. Isso geralmente é feito no arquivo principal do seu projeto.

    Main.hs
    {-# LANGUAGE DataKinds #-}
    {-# LANGUAGE TypeOperators #-}
    {-# LANGUAGE DeriveGeneric #-}
    {-# LANGUAGE OverloadedStrings #-}
    
    module Main where
    
    import Servant
    import Network.Wai
    import Network.Wai.Handler.Warp
    import Api
    import Data.Aeson (ToJSON)
    import GHC.Generics (Generic)
    
    server :: Server API
    server = return [Produto 1 "Produto 1" 10.0, Produto 2 "Produto 2" 20.0]
        :<|> 
        \id -> return (Produto id "Produto exemplo" 15.0)
    
    app :: Application
    app = serve (Proxy :: Proxy API) server
    
    main :: IO ()
    main = run 8080 app

  6. Compilando e Executando a Aplicação

    Execute o seguinte comando para compilar e lançar a aplicação. A API estará disponível em `http://localhost:8080/produtos`.

    commands
    stack build
    stack exec api-restful

  7. Testando a API

    Utilize ferramentas como Postman ou cURL para testar os endpoints da API que você acabou de criar. Aqui estão alguns exemplos utilizando cURL.

    commands
    # Listar todos os produtos
    curl -X GET http://localhost:8080/produtos
    # Obter produto por ID
    curl -X GET http://localhost:8080/produtos/1

  8. Implementando Testes Unitários

    Para garantir que sua API está funcionando como esperado, crie testes unitários utilizando o Hspec. Adicione a biblioteca ao seu `package.yaml` e configure seus testes.

    package.yaml
    test-dependencies:
      - hspec
      - servant-client
    
    -- Teste de exemplo
    module MainSpec where
    
    import Test.Hspec
    import Api
    
    main :: IO ()
    main = hspec $ do
      describe "Produto API" $ do
        it "Retorna todos os produtos" $ do
          -- Código para testar o endpoint

  9. Executando Testes

    Após implementar os testes, você pode executá-los utilizando o comando abaixo. Certifique-se de que o seu projeto está corretamente configurado e que todos os testes estão passando.

    commands
    stack test

Conclusão

Neste tutorial, você aprendeu como construir uma API RESTful em Haskell utilizando o Servant, desde a configuração do ambiente de desenvolvimento até a implementação de rotas e testes. Com as habilidades adquiridas, você poderá desenvolver suas próprias APIs e expandir ainda mais seus conhecimentos em Haskell. Através da combinação de Haskell e Servant, você pode criar aplicações seguras e eficientes, aproveitando a robustez que a linguagem proporciona.

Hashtags

#Haskell #Servant #APIs #WebDevelopment #Stack #GHC