Introdução

Nesse tutorial, vamos explorar a criação de APIs RESTful utilizando Haskell, focando no framework Servant e na documentação automática com Swagger. Haskell é uma linguagem funcional que oferece uma abordagem única para o desenvolvimento de software, e o Servant permite definir APIs de forma declarativa. Vamos abordar desde a configuração do ambiente até a implementação de uma API completa, destacando boas práticas e a importância da documentação. Além disso, discutiremos como integrar a automação de testes e a integração contínua, fundamentais para garantir a qualidade do software. Este é um guia ideal para desenvolvedores que desejam aproveitar ao máximo o potencial de Haskell e Servant na construção de APIs.

Etapas

  1. Preparação do Ambiente de Desenvolvimento

    Certifique-se de ter o GHC (Glasgow Haskell Compiler) e o Cabal instalados no seu sistema. Você pode verificar se as ferramentas estão instaladas corretamente usando os comandos `ghc –version` e `cabal –version`. Se necessário, faça o download do instalador a partir do site oficial do Haskell.

    commands
    # Verificar versões instaladas
    ghc --version
    cabal --version

  2. Criando um Novo Projeto Haskell

    Utilize o Cabal para criar um novo projeto Haskell. Execute o seguinte comando para criar um projeto chamado ‘api-restful’: `cabal init`. Siga as instruções para configurar os detalhes do projeto, incluindo nome, descrição, e etc.

    commands
    # Criar novo projeto
    cabal init

  3. Adicionar Dependências Servant e Swagger

    Edite o arquivo `cabal.project` para adicionar as dependências necessárias para o Servant e Swagger. Adicione as linhas correspondentes às bibliotecas ‘servant’, ‘servant-server’ e ‘swagger2’. Essas bibliotecas são essenciais para a criação de APIs RESTful e documentação automática.

    cabal.project
    packages: .
    
    extra-deps: servant servant-server swagger2

  4. Definindo a API com Servant

    Crie um módulo Haskell para definir a API. Neste exemplo, vamos criar um simples CRUD para um recurso `Produto` com os métodos GET e POST.

    Api.hs
    {-# LANGUAGE DataKinds #-}
    {-# LANGUAGE TypeOperators #-}
    
    module Api where
    
    import Servant
    
    -- Definição da API
    type API = "produtos" :> Get '[JSON] [Produto]
          :<|> "produtos" :> ReqBody '[JSON] Produto :> Post '[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

    Crie o módulo principal para implementar o servidor que irá rodar a API definida anteriormente. Use `Servant` para criar os manipuladores das requisições.

    Main.hs
    {-# LANGUAGE DataKinds #-}
    {-# LANGUAGE TypeOperators #-}
    {-# LANGUAGE TypeApplications #-}
    
    module Main where
    
    import Servant
    import Network.Wai
    import Network.Wai.Handler.WebSockets
    import Network.Wai.Handler.Simple
    import Network.HTTP.Types (status200)
    import Api
    
    main :: IO ()
    main = do
        putStrLn "Servidor iniciado na porta 8080"
        run 8080 app
    
    app :: Application
    app = serve (Proxy @API) server
    
    server :: Server API
    server = return [Produto 1 "Produto 1" 20.0]
             :<|> addProduto
    
    addProduto :: Produto -> Handler Produto
    addProduto produto = return produto

  6. Documentação Automática com Swagger

    Adicione a documentação Swagger à sua API. Configure o módulo para expor o endpoint da documentação gerada automaticamente com Swagger.

    Swagger.hs
    {-# LANGUAGE DataKinds #-}
    {-# LANGUAGE TypeOperators #-}
    
    module Swagger where
    
    import Servant
    import Servant.Swagger
    
    -- Definindo a documentação
    apiSwagger :: API -> Swagger
    apiSwagger = toSwagger (Proxy :: Proxy API)
    
    swaggerAPI :: Swagger
    swaggerAPI = apiSwagger api

  7. Testes Unitários

    Implemente testes para validar sua API. Utilize a biblioteca ‘hspec’ para realizar os testes de unidade das funções manipuladoras.

    Spec.hs
    import Test.Hspec
    import Network.Wai
    import Network.Wai.Test
    import Api
    
    main :: IO ()
    main = hspec $ do
        describe "API Produtos" $ do
            it "retorna uma lista de produtos" $ do
                -- Escreva aqui os testes para a API
    

  8. Configurando Integração Contínua

    Integre um serviço de CI/CD como GitHub Actions ou Travis CI para automatizar o processo de build e testes. Crie um arquivo de configuração que descreva como seu projeto deve ser construído e testado.

    .github/workflows/haskell.yml
    name: Build and Test
    on: [push, pull_request]
    jobs:
      build:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v2
          - name: Install Haskell
          run: curl -sSL https://get.haskellstack.org/ | sh
          - name: Build
            run: stack build
          - name: Test
            run: stack test

  9. Executando a Aplicação

    Utilize o comando Cabal para compilar e executar a aplicação. Realize os testes com `hspec` e valide se todos os testes estão passando.

    commands
    # Compilar e executar a aplicação
    cabal run
    # Rodar os testes
    cabal test

    curl_examples
    # Listar todos os produtos
    curl -X GET http://localhost:8080/produtos
    # Criar um novo produto
    curl -X POST -H "Content-Type: application/json" -d '{"nome":"Novo Produto", "preco":99.99}' http://localhost:8080/produtos

Conclusão

Neste tutorial, você aprendeu a desenvolver uma API RESTful utilizando Haskell e o framework Servant, implementando uma documentação automática com Swagger. Assim como estabelecemos uma base sólida com a implementação de testes e integração contínua, você está agora preparado para levar seus projetos Haskell para o próximo nível. Essa abordagem não apenas melhora a qualidade do código, mas também agiliza o desenvolvimento de software em equipe. Aproveite as possibilidades que Haskell e Servant oferecem na construção de APIs robustas.

Hashtags

#Haskell #Servant #API #Swagger #IntegraçãoContínua #DesenvolvimentoDeSoftware