API - Acessando APIs REST com PowerShell Invoke-RestMethod


 Você sabia que podemos consumir APIs REST usando o PowerShell através do Cmdlet Invoke-RestMethd ? Acompanhe este artigo e veja o que podemos fazer...

Vamos iniciar fazendo algumas definições e apresentando alguns conceitos básicos que envolvem os recursos que iremos apresentar. (vou usar a documentação da Microsoft)


Começando com o PowerShell que é uma solução de automação de tarefas multiplataforma que consiste em um shell de linha de comando, em uma linguagem de script e uma estrutura de gerenciamento de configuração. O PowerShell pode ser executado no Windows, Linux e macOS.

Os comandos do PowerShell são conhecidos como cmdlets (pronuncia-se comand-lets). Além dos cmdlets, o PowerShell permite executar qualquer comando disponível no seu sistema.

Os cmdlets são comandos nativos do PowerShell, não executáveis autônomos, que são coletados em módulos do PowerShell e que podem ser carregados sob demanda e podem ser gravados em qualquer linguagem da plataforma .NET compilada ou na própria linguagem de script do PowerShell.

Os cmdlets são baseados em classes .NET e contam com o uso de objetos .NET. Assim, os cmdlets podem receber objetos como entrada e entregar objetos como saída, que podem alimentar a entrada de objetos subsequentes, permitindo que os cmdlets formem um pipeline de comando.

Apresentando o cmd-let Invoke-RestMethod

Quando você precisa recuperar ou enviar dados para uma API REST, você precisa de um cliente.

No mundo do PowerShell, esse cliente é o cmdlet Invoke-RestMethod.

Esse cmdlet envia solicitações HTTP usando vários métodos HTTP (GET, POST, PUT, DELETE) para endpoints da API REST sendo que os métodos HTTP instruem as APIs REST a realizar várias ações a serem executadas em um recurso e os serviços REST retornam dados estruturados.

Dessa forma o cmdlet Invoke-RestMethod dá suporte a todos os métodos HTTP, incluindo autenticação, envio de diferentes cabeçalhos HTTP, corpos HTTP e também traduz automaticamente respostas JSON e XML para objetos do PowerShell.

Os requisitos necessários para acompanhar o artigo é ter o PowerShell instalado no seu ambiente usando a versão 7.0 ou superior.

Para saber a versão do seu PowerShell abra uma janela do PowerShell e digite o comando : $PSVersionTable

Para atualizar o PowerShell (Windows 10) abra uma janela do PowerShell como administrador e digite o comando:

winget install Microsoft.PowerShell

Tendo o seu ambiente atualizado e pronto podemos iniciar.

Retornando dados usando o método GET

Vamos começar com o exemplo mais simples que existe : Consultar uma API REST com uma solicitação GET usando o cmdlet Invoke-RestMethod
 
Para enviar uma solicitação GET simples para um endpoint da API REST, você precisará apenas de um parâmetro: a Uri.

O parâmetro Uri é que informa ao Invoke-RestMethod onde está o endpoint que você quer consumir.

Vamos escolher uma API pública que poderemos acessar. As APIs disponíveis em https://jsonplaceholder.typicode.com/ permitem o acesso público oferecem  um  serviço RESTful que podemos acessar de forma gratuita e obter dados fictícios.

Assim a requisição para : https://jsonplaceholder.typicode.com/posts vai retornar todos dados de posts no formato JSON abaixo:

Podemos obter também os dados pelo id montando uma  requisição do tipo : https://jsonplaceholder.typicode.com/posts/id

Observe que o id no final da URl é o id do usuário e é por onde a API espera vai encontrar o ID.

Vamos abrir uma janela do PowerShell e digitar o comando:

Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/posts"

Quando o endpoint REST https://jsonplaceholder.typicode.com/posts retorna dados, ele não os retorna em objetos do PowerShell, como você vê acima. Ele retorna dados no formato JSON mas o cmdlet Invoke-RestMethod converte automaticamente o JSON em objetos do PowerShell para você.

Você pode ver abaixo que o PowerShell converteu a saída para o tipo PSCustomObject examinando um único item na matriz do PowerShell e executando o método GetType() nele.

Para isso digite os comandos :

# Armazena a resposta da API na variável ($Posts).
$Posts = Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/posts"

# Executa o método GetType() contra o primeiro item no array identificado pelo indice 0
$Posts[0].GetType()

Recuperando dados com o uso de parâmetros de consulta

Normalmente, enviar uma solicitação GET para uma API REST envolve mais do que apenas um simples request para um endpoint. Em vez disso, você pode ter que passar parâmetros para especificar exatamente o que você precisa da API.

Vamos abordar como passar parâmetros para um endpoint usando o parâmetro Body.

Para enviar parâmetros de consulta com Invoke-RestMethod, nesta abordagem você possui duas opções :

  1. Você pode anexar diretamente os parâmetros na URI, conforme mostrado abaixo, onde passamos um userId igual a 1 e um id igual a 8.

    https://jsonplaceholder.typicode.com/posts?userId=1&id=8
     
  2. Ou você pode definir os parâmetros no corpo HTTP usando o parâmetro Body como uma tabela de hash.

        Para isso vamos criar uma tabela hash contendo os pares de chave/valor do parâmetro de consulta, conforme a seguir :

              

       
Por fim, vamos fornecer a variável $Body ao parâmetro Body, conforme mostrado abaixo.

       

Ao executar temos que o endpoint retorna apenas o item de postagem que você está procurando conforme foi especificado.

Uma forma bem simples de obter resultados é passar o parâmetro diretamente a URI e definir o método do request. Para isso podemos usar o seguinte comando para retornar o post com o id igual a 3 :

Invoke-RestMethod https://jsonplaceholder.typicode.com/posts/3 -Method GET

Enviando dados para uma API com o método POST HTTP

Nos exemplos anteriores, estávamos consultando dados de uma API REST usando solicitações HTTP GET. Com isso podemos ler os dados enviados de volta, mas a leitura é apenas metade da história com muitas APIs REST. As APIs REST devem oferecer suporte a um modelo CRUD completo para que você possa interagir com o serviço.

Quando você precisar fazer alterações em um serviço que fornece uma API, não usará uma solicitação GET HTTP; você usará uma solicitação “gravável” como POST.

Usando o endpoint anterior da API REST, vamos agora criar um novo item post em vez de apenas lê-los.

1. Primeiro, crie uma tabela de hash incluindo todos os atributos para o endpoint da API de postagens. Você verá abaixo que o endpoint específico do tutorial permite criar um novo item post com title, body e userId.

2. Em seguida, converta a tabela de hash representada na variável $Body em uma string JSON armazenando-a em uma nova variável $JsonBody.



3- Por fim, crie os parâmetros necessários e execute Invoke-RestMethod. Observe abaixo que agora você deve usar o parâmetro Method com um valor de Post. Sem usar o parâmetro Method, o padrão Invoke-RestMethod envia uma solicitação GET.

Além disso, muitas APIs REST exigem que você especifique o ContentType indicando o cabeçalho HTTP Content-Type no qual o corpo está armazenado. Neste exemplo, você deve usar application/json.



Veja o resultado exibindo o novo post que foi incluído usando o método POST.

Uma outra forma de obter o mesmo resultado é enviar tudo em um comando só:

Invoke-RestMethod https://jsonplaceholder.typicode.com/posts -Method POST -Body (@{title="Novo Teste"; body="Novo Body"; userId=1} | ConvertTo-Json) -ContentType "application/json"



Enviando dados de formulário com Invoke-RestMethod

Alguns endpoints da API REST podem exigir que você envie dados por meio do tipo de conteúdo HTTP multipart/form-data. Enviar um tipo de conteúdo diferente com Invoke-RestMethod é um pouco mais fácil do que usar JSON. Desde o PowerShell 6.1.0, agora você pode usar o parâmetro Form.

O parâmetro Form fornece uma maneira conveniente de adicionar objetos multipart/form-data a uma solicitação sem a necessidade de usar a classe .NET System.Net.Http.MultipartFormDataContent diretamente.

Para enviar dados de formulário com Invoke-RestMethod, primeiro, crie uma tabela de hash com cada item como antes.

$Form = @{
    title = "foo"
    body = "bar"
    userId = 1
}

Por fim, basta passar a tabela de hash para o parâmetro Form, conforme mostrado abaixo.

Uma outra forma é enviar tudo em um único request:

Invoke-RestMethod https://jsonplaceholder.typicode.com/posts -Method PUT -Body (@{title="Novo titulo alterado"; body="Macoratti"; userId=1}) -ContentType "application/x-www-form-urlencoded"

Vimos como usar o cmdlet Invoke-RestMethod para fazer a interação com APIs REST muito mais fácil do que com solicitações da Web padrão.

Existem outras possibilidades e outros usos que não foram abordados neste artigos e que em breve iremos apresentar.

"E o seu mandamento é este: que creiamos no nome de seu Filho Jesus Cristo, e nos amemos uns aos outros, segundo o seu mandamento."
1 João 3:23

Referências:


José Carlos Macoratti