Criando uma API REST no mod_harbour
Tags: braziliandevs
Published: 2022-04-12 14:26:40

Nesse tutorial, vamos criar e consumir uma API REST utilizando o mod_harbour. REST permite que voce acesse e trabalhe com serviços baseados na web. Mas antes de continuar esse tutorial, vamos ver de forma resumida o que é o REST e como funciona.

#### O que REST ?

REST é um acrônimo que significa **Re**presentacional **S**tate **T**ransfer. É um estilo de aquitetura que define um conjunto de restrições para desenvolvimento e consumo de serviços na web através do protocolo padrão HTTP. API REST é uma arquitetura de web service simples, fácil de implementar e stateless.

API REST é amplamente usado em aplicações web e mobile. E pode prover output de dados em diversos formatos como: JSON, XML e CSV.

#### Como uma API REST funciona

Requisições REST são relacionadas com operações CRUD (Create, Read, Update e Delete) no banco de dados. REST usa requisições GET, POST, PUT e DELETE. Vamos fazer uma rápida comparação dessas requisições com as operações CRUD:

- GET é usado para recuperar informações, o que é similar ao Read
- POST é usado para cruar novos registros, o que é similar ao Create
- PUT é usado para atualizar registros, o que é similar ao Update
- DELETE é usado para apagar registros, o que é similar ao Delete

#### Como criar e consumir uma API REST em mod_harbour

Vamos usar o formato JSON para consumir nossa API REST. É o formato mais simples e acho que também é o mais usado nos dias de hoje. Vamos desenvolver uma pesquisa através do código EAN de um produto para nosso exemplo. Vamos tentar manter o mais simples possível, então vamos usar a requisição GET para recuperar a informação.

#### Banco de dados utilizado

Para o nosso exemplo, vamos utilizar um banco de padrão DBF, aproveitando que o Harbour manipula esse tipo de arquivo nativamente. Nosso banco de dados já está criado como "produtos.dbf" e o índice correspondente "produtos.cdx". É um arquivo com apenas alguns registros, que serve tranquilamente para nossos testes.

#### Criando o arquivo API REST

Vamos criar um arquivo chamado API.PRG

```
function main()
   local hGet   := {=>} ,;
         hRet   := {=>} ,;
         cPath  := AP_GetEnv("DOCUMENT_ROOT")+"/api1/" ,;
         cAlias := ""
   //
   // Setar o content-type para o tipo correto 
   //
   AP_SetContentType( "application/json" )

   //
   // Testar se o método usado foi o GET
   //
   if AP_Method() == "GET"
      //
      // O retorno de AP_GetPairs() é um hash contendo todas as variáveis
      //
      hGet := AP_GetPairs()

      if HHasKey( hGet, "codbarra" ) .and. !empty(hGet["codbarra"])
         use (cPath + "produtos") shared new via "DBFCDX"
         set index to (cPath + "produtos.cdx")
         cAlias := alias()

         (cAlias)->(dbSetOrder( 1 ))
         if (cAlias)->(dbSeek( hGet["codbarra"] ))
            hRet['sucesso'] := .T.
            hRet['erro']    := ""
            hRet['descpro'] := alltrim((cAlias)->descricao)
         else
            hRet['sucesso'] := .F.
            hRet['erro']    := "Codigo de barra nao encontrado"
         endif
      else
         hRet['sucesso'] := .F.
         hRet['erro']    := "Falta informar o código de barras ou nome da variavel esta errado (deve ser 'codbarra')"
      endif

      ?? hb_jsonencode( hRet )
   else
      ?? "Requisição para esse exemplo dever ser GET"
   endif
RETURN NIL
```
Para testar o exemplo acima, podemos executar pelo browser da seguinte forma:

`localhost/api1/api.prg?codbarra=7896185932013`

e o resultado será um JSON, contendo:

```
{
  "sucesso": true,
  "erro": "",
  "descpro": "DACTIL OB C/30 DRG ............. .."
}
```

Poderíamos também alterar a forma como será construída a URL. Da forma que está não é "user-friendly". Teríamos que fazer alteração no arquivo .htaccess para que possa "entender" uma nova regra e permitir a digitação na forma:

`localhost/api1/api.prg/7896185932013`

Mas vamos deixar para um novo post. Acho que tem coisa mais importante: como autenticar usuario/senha gerando token JWT, como tratar desigualdades nas requisições GET (implementar LHS Brackets ou não vale a pena?), como "sanitizar" (olá PHP) de forma apropriada as requisições e mais.

Até o próximo post.