top of page
Foto do escritorReginaldo Silva

Azure Function para Analytics - HTTP Trigger - Criando uma API de CEP

Fala dataholics, esse post faz parte de uma série sobre Azure Function para Analytics, no episódio anterior vimos uma introdução sobre o tema e criamos uma Function básica com trigger de agendamento.


Posts:


No post de hoje veremos sobre a trigger HTTP e como podemos criar uma API básica.


Para o post de hoje criaremos um banco de dados de CEPs e endereços de todo o Brasil e iremos expor ele publicamente via API com Azure Function HTTP Trigger, abaixo o desenho que implementaremos.


O que veremos nesse post:

  • O que é uma API

  • Azure Function HTTP Trigger

  • Expondo seu PostgreSQL com uma API

  • Usando Postman para testes HTTP

  • Enviando parâmetros para uma HTTP Trigger

  • HTTP Status code

  • Métodos padrão de entrada GET e POST

  • Usando JSON.DUMPs para indentar JSON

  • Usando biblioteca REQUESTS para testar a API

  • Porque engenheiro de dados precisa conhecer isso

  • Resumo


Nesse post estou usando o contexto de uma API para mostrar a funcionalidade de uma trigger HTTP, embora, não adentraremos a fundo nas boas práticas de APIs, não abordarei sobre Azure API Managment e nem sobre RestFul APIs nesse tópico.

 

O que é uma API


No nosso mundo de engenharia é um requisito para maioria das vagas o conhecimento sobre manipulação de APIs, por ser uma tarefa bem corriqueira e comum no nosso dia a dia.


Mas você já entendeu de fato o que é uma API?


No sentido literal temos essa tradução: Application Programming Interface (Interface de Programação de Aplicação)


Mas sinceramente, para quem está lendo a primeira vez sobre API ficaria confuso com esses termos, vamos pensar de outra maneira.


Imagine que você trabalha em uma empresa fornecedora de um software de Service Desk, a famosa plataforma para abrir os tickets (JIRA, ServiceNow, Movidesk, ZenDesk etc.), vocês tem diversos clientes usando a plataforma e eles gostariam de ter acesso aos seus dados de forma mais simples e dinâmica para poderem automatizar rotinas ou mesmo integração com sistemas internos.


Quais são as possibilidades de liberar os dados da sua plataforma para todos os clientes de maneira controlada e escalável?


Liberar um login e senha para acessar o seu banco de dados?

Obviamente essa não é nem de perto uma opção concorda?! Imagine as queries SQL malucas que iriam aparecer e travar o seu banco de dados.

Num passado muito distante já trabalhei em alguns casos que o fornecedor confiava tanto (ou dependia tanto) no cliente que ele liberou o acesso ao banco de dados diretamente.


Liberar acesso para extrair arquivos CSVs?

Por muito tempo essa foi uma opção viável, embora, é muito trabalhosa e impossibilita automatizar fluxos e integrações com sistemas.

Essa seria uma opção apenas para baixar dados e gerar relatórios, ainda tem muito sistema que faz isso.


Liberar dados via API:

Essa vem sendo a opção adotada por todos os sistemas de mercado, hoje em dia é raro uma aplicação não ter uma API para acesso dos seus usuários ou integração com outros sistemas.

Quer um exemplo prático? Para quem utiliza a plataforma de Service Desk Movidesk, eles liberam uma API para que vocês possam consultar e manipular diversas informações da plataforma, dá uma conferida:

Com essa API, você pode fazer desde geração de relatórios customizados, quanto a criação e modificação de tickets, permitindo integração com outras plataformas.


Uma API cria uma ponte segura entre o seu banco de dados e os seus clientes e sistemas que desejam consultar e manipular dados da sua plataforma de forma dinâmica.

Com uma API você não precisa expor o seu BackEnd, exemplo, imagine que você utiliza PostgreSQL, você libera acesso para seus clientes no seu banco de dados (cenário hipotético), ai sua empresa decide migrar de PostgreSQL para MongoDB, todos os seus usuários\clientes vão precisar reescrever suas queries SQL para rodar no MongoDB, um grande transtorno seria gerado.


Além de não expor o seu BackEnd, você tem controle total de quem acessa, o que ela acessa e quando ela acessa, podendo fazer controles para melhorar a concorrência e escalabilidade, exemplo, algumas APIs você só pode consultar 1000 vezes por hora, pode implementar um limite máximo de retorno de linhas, então você garante que sua API não travará seu ambiente, outro ponto positivo, você tem controle total das queries que são disparadas contra o seu banco de dados, podendo escreve-las de forma performatica e indexada.


Por padrão, as APIs se comunicam através do protocolo HTTP e trocam informação utilizando o padrão JSON, isso facilita a automação e integração com diversas plataformas, existem diversos outros padrões e boas práticas na criação de APIs, embora esse não é o tópico aqui.


As APIs possuem métodos padrão de acesso, isso facilita muito o reaproveitamento do conhecimento, pois, quando você aprende muito sobre uma API, esse conhecimento é muito útil para manipular a maioria das APIs, exemplo essa tabela de métodos comuns.

Referência:


Espero que tenha ficado claro a principal funcionalidade de uma API, entendo que para maioria das pessoas esse conceito já está bem enraizado, mas se você esta começando agora, pode ser valioso entender isso cedo.


 

Azure Function HTTP Trigger


Agora entenderemos como o Azure Function pode nos ajudar quando falamos de API, no post anterior aprendemos sobre o básico e como criar uma Function que dispara com um timer programado usando CRON.


A Trigger de HTTP é uma maneira diferente de dispararmos o código da nossa função, com esse modelo podemos disparar nosso código via requisição HTTP, ou seja, você pode disparar uma Azure Function pelo seu navegador mesmo, claro que não é tão convencional, mas é uma possibilidade.


A trigger HTTP cria um endpoint que basicamente é uma URL onde podemos disparar através de código (Python, C#, Powershell...), navegadores, Webhooks, Postman, etc.


Basicamente se comportando como uma API, embora para dizer de fato que é uma API, você precisa se adequar a vários padrões de utilização, códigos de retorno, formato do retorno, autenticação entre outros.


Chega de falar, vamos criar nossa primeira Function HTTP e simular uma API de CEPs.


Para o ambiente de hoje criei a um banco de dados PostgreSQL com dados de CEP em 4 tabelas:


Utilizei esse projeto do Github para criar a base de dados: https://github.com/jordaniodev/cep-brasil/tree/master

Embora esse projeto seja para MySQL, adaptei os scripts para usar no PostgreSQL, abaixo um exemplo de uma query SQL unificando as tabelas com JOIN.


Agora criaremos o código Python que receberá uma requisição HTTP e irá realizar a consulta SQL no banco de dados PostgreSQL e retornar a informação para quem solicitou.


Todo o código estará disponível no Github, abaixo explicarei os principais trechos.


Seguindo o mesmo padrão do post anterior, criei uma Function, mas dessa vez escolhi o tipo HTTP trigger ao invés Timer Trigger, o passo a passo para criação é o mesmo.

Detalhe importante, note que a query SQL que estou usando realiza alguns JOINs para poder retornar o endereço completo, a documentação das tabelas esta no github indicado.


O restante do código é bem simples veja a imagem abaixo, no primeiro bloco, se foi encontrado o CEP informado no PostgreSQL ele devolve as informações para a requisição e código 200 de sucesso.


No segundo bloco é se o CEP não foi encontrado no banco de dados, então devolve uma mensagem e código 204 que significa que a requisição teve sucesso, mas não retornou nenhuma informação.


No terceiro bloco é no caso do CEP não ter sido informado nos parâmetros da requisição HTTP, retorna uma mensagem mais código 404 de não encontrado, aqui só um exemplo de como podemos manipular o código de retorno.

Quer saber mais sobre HTTP Status Code: HTTP STATUS CODE.


Após codificado e testado localmente, publicaremos nossa function para a Function App.

Note que ao final do Deploy, ele retorna a URL da nossa HTTP trigger.



Ah Reginaldo, mas não fui eu quem publicou, onde consigo pegar a URL da minha trigger HTTP?

No portal Azure, dentro da sua Function vá na aba de Code + Test e no botão Get Function URL.


Um detalhe importante, assim como todas as APIs, você precisa definir quais métodos a sua trigger suportará, exemplo, defini que os métodos GET e POST são aceitos, embora, não implementamos nada para o método POST ainda.


Bora testar?


A minha URL é essa aqui abaixo, se quiser brincar com ela para testar, deixarei disponível durante um período, para os engaçadinhos que quiserem tentar fazer um SQL Injection, fica a vontade, só tem 4 tabelas nesse database.


URL:

A base de dados está atualizada até 2019 então você encontrará quase todos os endereços que pesquisar, mas já aviso, não pendure nessa API rs, ela morrerá em breve sem aviso prévio.


Testaremos primeiro no navegador:


E como passar parâmetros na requisição HTTP usando URL?

Quando passamos na URL direto, podemos usar o padrão ?[nome parametro]=[valor]

Embora, alguns parâmetros, como o Headers você não conseguirá fazer via navegador, então a melhor maneira será via código ou Postman.


Outro ponto, note que no navegador você não consegue ver o Status Code de retorno, você conseguiria ver no modo desenvolvedor, mas daria muito trabalho, então para isso, testaremos de uma forma diferente.


Testaremos com Postman:

Se você ainda não conhecia o Postman, deveria, é uma plataforma extremamente útil para desenvolvermos e testarmos nossas requisições HTTP.


Com ela podemos criar queries complexas com parâmetros, autenticação, Headers e ainda recebermos um retorno em JSON e formatá-lo de uma maneira mais legível, entre outras funcionalidades muito tops.


Note que estamos fazendo uma requisição do tipo GET (ou seja, solicitando dados) e passando CEP como parâmetro.

O Status code de retorno foi 200 e no Body podemos ver o endereço retornado.


Informando um CEP que não foi encontrado na nossa base de dados PostgreSQL: Status code 204.


Nenhum CEP informado: Status code 404.


Ah, mas Reginaldo, sua API não retorna JSON?

A minha API retorna o que eu quiser rs, é claro que existem padrões de mercado, mas não é obrigatório, você pode retornar do jeito que quiser, embora, no mundo real todas as APIs retornam JSON para padronizar e facilitar a comunicação entre as aplicações.


Mas isso também é bem simples de resolver, podemos transformar nosso resultado em JSON de várias maneiras, seja formatando manualmente, usando a Lib JSON no Python ou retornando direto do banco de dados como JSON, no PostgreSQL temos uma função que já faz isso a TO_JSON():

Destaque para esse trecho:

contentJson = json.dumps(row, ensure_ascii=False, indent=4)

Aqui uso a função JSON.DUMPS para formatar o meu JSON e deixar ele indentado, também destaque para esse parâmetro ensure_ascii para manter nossos caracteres especiais.

Resultado transformado em JSON:


Testaremos nossa API com Python:

Usando a biblioteca Requests e Json podemos fazer um script bem simples como o abaixo:


Em posts futuros veremos como podemos trabalhar com requisições do tipo POST e usar uma autenticação básica de token.


Espero que tenha gostado de aprender um pouco mais sobre Azure Function e suas funcionalidades com triggers do tipo HTTP.

 

Resumo


As triggers HTTPs tem um papel muito importante no ecossistema de aplicações e microsserviços, podendo disponibilizar endpoints para APIs como vimos hoje ou integração com sistemas de forma simplificada sem precisar expor o nosso ambiente interno, tendo controle de todas as queries que serão executadas e dando poder aos usuários para poderem criar seus próprios relatórios e automações.


Para o engenheiro de dados é crucial ter o conhecimento básico de criar requisições HTTP para poder consultar APIs de maneira eficiente, saber trabalhar com as diversas opções de autenticação, criar queries complexas, manipular Header, requisições do tipo POST e PATCH e os principais Status Codes, veremos boa parte desses temas nessa série sobre Azure Function.


Fiquem bem e até a próxima.

Link Github:

Se quiser aprender mais sobre APIs com Azure Function, siga essa doc:

209 visualizações0 comentário

Comments


Post: Blog2 Post
bottom of page