Open ppKrauss opened 4 years ago
Solução meio gambiarra: organizar catch-all functions por tipo de retorno: se o tipo é o mesmo, o PostgreSQL permite usar uma só função com CASE para as demais.
Outra opção....
manter uso de cath-all apenas para retorno JSON e funções temporárias ou mais simples.
usar parametrização padronizada, api.f(uri text, args text)
.
manter uso de retornos tabulares padronizados para simplificar descrição da API (lembrando que podemos fazer ?select=a,j->x
para simplificações)... Ou seja, api.f(uri text, args text) RETURNS (LIKE api.ttpl_x)
.
manter ideia de sintaxe de nome da função compatível com sintaxe do endpoint
Resolvido no NGINX:
# API /v1{formatoSaida}/{modulo}/{funcao}/{parametros}
location ~ /v1(?:\.json)?/([a-z_][a-z0-9_]*)/([a-z_][a-z0-9_]*)/(.+) {
proxy_pass http://localhost:3103/rpc/uridisp_$1_$2?p_uri=$3&$args;
}
location ~ /v1\.csv/([a-z_][a-z0-9_]*)/([a-z_][a-z0-9_]*)/(.+) {
proxy_set_header Accept 'text/csv';
proxy_pass http://localhost:3103/rpc/uridisp_$1_$2?p_uri=$3&$args;
}
E resolvido no Postgresql, mantendo
api.uri_dispatch_parser()
), e todas as "funções globais", relativas a módulos multi-projeto. Exemplos do módulo Eclusa do Projeto DigitalPreservation:
Fechando a arquitetura em conformidade com http://addressForAll.org/api e step01-iniApi.sql
... usar api.addressforall.org/v1.json/
como listagem de urls ou de endpoints, ver https://api.github.com/
equanto request json de api.addressforall.org retorna versoes e demais metodos.
Outro problema, o fetch() do Javascript nao permite CORS (? ver fetch-crossorigin), ou algo se passa com /rpc NGINX vs /_sql direto .... Aceitou http://api-test.addressforall.org/_sql/origin_agg1 mas nao aceitou http://api-test.addressforall.org/_sql . Passou a aceitar com mode:no-cors
mas dai dando erro "Uncaught (in promise) SyntaxError: JSON.parse: unexpected end".
Por hora temos 3 motivacoes para a funcoes de RPC com sintaxe de filtragem no NGINX:
Tentando agrupar assuntos correlatos, trouxe https://github.com/AddressForAll/specifications/discussions/9 e https://github.com/AddressForAll/WS/issues/32 de Novembro/2021 para cá:
É necessário regrar um pouco melhor a oferta de APIs de cada domínio... Sugere-se mais ou menos o seguinte:
API implementada por um período de teste em modo teste, para comprovar que não tem "efeitos colaterais" no servidor, e que contempla ambos, a especificação técnica inicial e as necessidades reais de quem usa.
Controle dos nomes de API através de versionamento e jurisdição. Por exemplo a API do batista seria versão 1 (v1) da Colômbia, então o nome seria algo como API.addressforall.org/v1/CO/search
Controle interno dos nomes de função no PostgreSQ/PostgREST, dentro do SQL-schema API: o acesso GET e POST se faz no NGINX por algo como proxy_pass http://localhost:$porta/rpc/uridisp_$1_$2?p_uri=$3&$args
onde $1
é o módulo funcional (ex. addressfind
), $2
o nome da API (ex. search
), $3
o parâmetro default contendo o "resto do path na URL" e em $args
os demais parâmetros, quando houverem. A declaração de função será sempre seguindo o template CREATE FUNCTION api.uridisp_{module}_{name}(p_uri text, {args}) RETURNING jsonb .... IMMUTABLE
.
Nesta issue discutiremos diretamente o draft da documentação e a sua implementação final.
Depois de avançar na discussão, https://github.com/AddressForAll/specifications/discussions/9
Existem duas estratégias para implementar a resolução de parâmetros GET por regular expression:
Uma eventual vantagem é o tratamento centralizado de erros; a desvantagem é uma pequena perda de performance.
As vantagens seriam performance e gradualidade (permite automação mais tardia).
A estratégia 1 foi utilizada no primeiro rascunho do projeto. A estratégia 2 parecia ser a melhor, todavia não foi encontrada solução compacta no NGINX para resolver os 3 casos distintos (CSV/JSON/HTM). Tendo isso em vista, voltamos à estratégia inicial.
Problemas:
select to_jsonb(t) from f($1) t
e depois agregadas como array jsonb. Ainda assim não tem como retornar CSV nas condições atuais.setof record
, surgem comjsonb_populate_record
ejsonb_to_record
. Não tem como retornar "tipo record" para o CSV pois não existe tipo genérico.