Skip to content
אצלי
Go back

Um cliente de API dentro do Standard Notes, com sintaxe .http e criptografia ponta a ponta

Editor API Client dentro do Standard Notes, com requisições em sintaxe .http à esquerda e, à direita, a resposta de cada bloco com status, tempo, tamanho e corpo

Também disponível em inglês: An API client inside Standard Notes, with .http syntax and end-to-end encryption.

Uso o Standard Notes desde abril de 2024, como contei no Hora do café #3. É um app de notas gratuito, open source e com criptografia ponta a ponta, e dá para estendê-lo com editores customizados.

O StandardNotes-APIclient é um desses editores: um cliente de API HTTP em que as requisições ficam no corpo da nota, em texto puro. Tokens, payloads e variáveis herdam a criptografia ponta a ponta do resto dos seus dados, algo que os clientes REST web normalmente não oferecem.

Standard Notes com o editor API Client aberto sobre a nota "demo plugin". À esquerda, a lista de notas. No centro, o texto em sintaxe .http, com as variáveis @host e @token e três blocos: Echo POST, Status check e CRUD example. À direita, os três blocos com o botão Run. O primeiro ainda não foi executado, o segundo mostra o retorno 201 em 289 ms, e o terceiro, um GET no jsonplaceholder, mostra 200 em 13 ms, 292 bytes e o JSON do post

Como funciona

O formato é o .http, o mesmo do REST Client do VS Code e do kulala.nvim. A nota inteira é um arquivo assim:

@host = https://httpbin.org
@token = your-secret-token

### Echo POST
POST {{host}}/post
Content-Type: application/json

{"plugin": "standardnotes-apiclient"}

### Status check
GET {{host}}/status/201
Authorization: Bearer {{token}}

Cada ### Título abre um bloco. Variáveis se declaram com @nome = valor e entram com {{nome}}, e uma variável pode referenciar as anteriores. Ambientes também ficam no arquivo: @nome.staging = valor cria o valor para staging, e @env = staging define o ativo. Na lista de variáveis, os valores de nomes que contêm token, secret, key, password ou auth ficam mascarados até você apertar show.

O botão Run de cada bloco executa só aquela requisição, e a resposta aparece logo abaixo: status colorido, tempo, tamanho, cabeçalhos recolhíveis e corpo. Imagens ganham pré-visualização e as demais respostas binárias podem ser baixadas. As respostas ficam só em memória, nunca são gravadas na nota, e o texto da nota não é alterado por uma execução. Ctrl/Cmd+Enter no texto executa a requisição sob o cursor.

Como tudo é texto, a busca global do Standard Notes encontra uma requisição pela URL, pelo nome de um cabeçalho ou pelo título do bloco, sem abrir o editor. E um export da nota continua legível em qualquer outro cliente que fale .http.

Encadeamento e verificações

Requisições podem alimentar umas às outras. Uma linha # @name login dá um nome à requisição e, depois que ela roda, as seguintes podem ler a resposta registrada: {{login.response.body.$.json.token}} pega um campo (um subconjunto de JSONPath: $, .campo, [índice] e [*]) e {{login.response.headers.X-Token}} pega um cabeçalho. As referências são resolvidas na hora da execução e nunca são gravadas na nota.

### Login
# @name login
POST {{host}}/post
Content-Type: application/json

{"token": "abc123"}

### Use the token
GET {{host}}/bearer
Authorization: Bearer {{login.response.body.$.json.token}}
# @assert status == 200
# @assert body.$.token exists

O Run all executa todas as requisições na ordem do arquivo, esperando cada uma, de modo que uma requisição encadeada lê a resposta da anterior, e para na primeira falha.

As linhas # @assert, no estilo do kulala.nvim, são conferidas contra a resposta e aparecem como passou ou falhou. O lado esquerdo pode ser status, headers.<nome>, body ou body.$.caminho, e os operadores são ==, !=, >, <, >=, <=, exists e not exists. Uma asserção malformada nunca passa em silêncio.

As variáveis dinâmicas são geradas a cada execução e nunca salvas: {{$uuid}}, {{$timestamp}}, {{$randomInt 1 10}} e {{$datetime}}.

Algumas coisas menores. O Copy as cURL de um bloco copia a requisição como um comando curl, com as variáveis já resolvidas e cada valor entre aspas para o shell. O bloco avisa sobre variáveis não resolvidas e sobre cabeçalhos que o navegador nunca envia, como Host ou Cookie. Dá para chegar aos blocos pelo teclado, com Tab e as setas.

Instalação

  1. No Standard Notes (web ou desktop), abra Preferences, depois Plugins.

  2. No fim da página, cole a URL abaixo em Install Custom Plugin:

    https://esli.cafe/StandardNotes-APIclient/ext.json
  3. Crie uma nota, abra o menu Editor e escolha API Client.

Uma nota vazia mostra o botão Add sample, que preenche o texto com requisições de exemplo contra o httpbin.org e o jsonplaceholder. Quem quiser só ver funcionando pode usar a demo online, sem instalar nada. Nela o texto fica no localStorage do navegador.

Limites

As requisições saem do navegador (ou do app desktop), então só endpoints com CORS habilitado respondem direto do editor. Para os demais, o README lista um proxy local companion como planejado, e ele ainda não saiu. Enquanto isso, é preciso usar um endpoint que mande os cabeçalhos CORS.

Executar uma requisição manda, claro, a requisição descrita para o endpoint de destino. Fora isso, nada é armazenado nem transmitido para outro lugar.

O plugin está na v0.5.2, licença AGPL-3.0, e o código fica em github.com/Esl1h/StandardNotes-APIclient. Foi construído sobre o editor-kit do Standard Notes.


Share this post on:

Previous Post
Kanban inside Standard Notes, with the board saved as Markdown
Next Post
An API client inside Standard Notes, with .http syntax and end-to-end encryption