20 de janeiro de 2024

APEX_WEB_SERVICE O Guia Definitivo



 

Introdução

APEX_WEB_SERVICE é de longe minha API APEX Pl/SQL favorita. Reduz drasticamente o esforço de chamar serviços Web externos do banco de dados Oracle. Nesta postagem, abordarei primeiro os principais conceitos que você precisa saber e, em seguida, revisarei vários casos de uso em que usei APEX_WEB_SERVICE para tornar minha vida mais fácil.

Ao lidar com APIs REST, existem duas maneiras principais de passar informações adicionais para a API REST. Isso ocorre por meio de cabeçalhos HTTP e parâmetros de string de consulta.

Normalmente você usa cabeçalhos HTTP para transmitir informações a uma API REST. No exemplo abaixo, estou solicitando a utilização da versão 2.1 da API. Nota : Cabeçalhos HTTP também são usados ​​para passar tokens de autorização, mas APEX_WEB_SERVICE cuida disso para você (mais sobre isso mais tarde).

apex_web_service.set_request_headers 
 (p_name_01   => 'Prefer', 
  p_value_02  => 'apiversion=2.1');


Limpando cabeçalhos HTTP existentes

  • É sempre uma boa ideia usar apex_web_service.clear_request_headerspara limpar quaisquer cabeçalhos HTTP existentes. Isso é importante se você ainda tiver cabeçalhos definidos de uma chamada anterior para apex_web_service.

  • Você também pode passar TRUE para o booleano p_reset to apex_web_service.set_request_headers e ele limpará todos os cabeçalhos existentes.

-- Opção 1 - limpar cabeçalho antes de chamar set_request_headers

apex_web_service.set_request_headers;

-- Opção 2 - limpar os cabeçalhos existentes enquanto define novos.
apex_web_service.set_request_headers 
 (p_name_01   => 'Prefer', 
  p_value_02  => 'apiversion=2.1',
  p_reset     => TRUE);

  • Você pode passar até cinco cabeçalhos de solicitação para apex_web_service.set_request_headers.

Parâmetros de string de consulta normalmente são usados ​​para passar parâmetros para a API REST que você chama. Quando visualizados em uma URL de solicitação REST, eles são vistos como um '?' marca seguida por uma lista delimitada por '&' de pares 'parâmetro=valor'.

?lat=32.866889&lng=-117.257139&date=today&formatted=0

APEX_WEB_SERVICE simplifica a passagem de parâmetros, permitindo que você preencha dois arrays PL/SQL, um com uma lista de nomes de parâmetros e outro com uma lista de valores de parâmetros. A string de consulta acima pode ser representada da seguinte maneira.
DECLARE
  lt_parm_names      apex_application_global.VC_ARR2; 
  lt_parm_values     apex_application_global.VC_ARR2; 

BEGIN
  lt_parm_names(1)  := 'lat'; 
  lt_parm_values(1) := '32.866889'; 
  lt_parm_names(2)  := 'lng'; 
  lt_parm_values(2) := '-117.257139'; 
  lt_parm_names(3)  := 'date'; 
  lt_parm_values(3) := 'today'; 
  lt_parm_names(4)  := 'formatted'; 
  lt_parm_values(4) := '0'; 
END;

Você pode então passar os parâmetros usando APEX_WEB_SERVICE os parâmetros p_parm_name e p_parm_value(exemplos a seguir).

Ao chamar APIs remotas, nunca podemos ter certeza de quanto tempo elas levarão para responder. Às vezes, precisamos esperar mais tempo para que as solicitações sejam concluídas ou encurtar o período de espera para que possamos falhar mais rapidamente.

APEX_WEB_SERVICElida com tempos limite por meio do p_transfer_timeoutparâmetro. Você pode alterar o tempo limite padrão (180 segundos) passando um número de segundos para este parâmetro.

Você não irá longe até criar uma ACL para permitir que o APEX faça solicitações de saída para o serviço Web que você está tentando chamar. ACLs são a forma do Oracle Database limitar quais usuários podem fazer chamadas para quais endpoints. Ao criar a ACL, você precisa especificar o esquema APEX atual como principal_name, por exemplo, o principal_name seria APEX_230200para APEX 23.2.

-- Examplo de ACL para permitir o esquema APEX_230200 
--   conectar o acesso a qualquer host'*'
BEGIN
    DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
        host => '*',
        ace => xs$ace_type(privilege_list => xs$name_list('connect'),
                           principal_name => 'APEX_230200',
                           principal_type => xs_acl.ptype_db));
END;

Quase todos os serviços da web possuem HTTPSterminais. Isso significa que APEX_WEB_SERVICE deve repassar um certificado público e a solicitação ao Web Service. O banco de dados Oracle lida com isso armazenando esses certificados em uma carteira TLS de banco de dados. As carteiras TLS são criadas no sistema de arquivos do servidor de banco de dados.


Você precisa obter o certificado antes de criar a carteira DB TLS. A maneira mais fácil de obter o certificado para um serviço web é chamá-lo em seu navegador, visualizá-lo e exportar o certificado raiz para um arquivo '.cer'.


Você pode então copiar o arquivo '.cer' para o servidor de banco de dados e criar uma carteira de banco de dados da seguinte maneira:
-- Encontre um lugar para colocar o wallet no servidor do BD
-- Um bom lugar é ao lado do xdb_wallet
-- Comece acessando o Administrador em $ORACLE_HOME

cd $ORACLE_HOME/admin-- Find the xdb_wallet
find . -type d -name "xdb_wallet"
./devdb/xdb_wallet

-- Nesse caso a carteira xdb_wallet está sob 

$ORACLE_HOME/admin/devdb
cd $ORACLE_HOME/admin/devdb
mkdir tls_wallet
cd tls_wallet
orapki wallet create -wallet . -auto_login
orapki wallet add -wallet . -trusted_cert -cert ABC.crt -auto_login


-- auto_login indica que o wallet(carteira) pode ser usada em qualquer servidor.


A maneira mais fácil de fazer referência a uma carteira TLS de banco de dados no APEX é configurá-la em Serviços de Administração (o espaço de trabalho INTERNO).


APEX_WEB_SERVICE usará a carteira TLS configurada aqui, a menos que você informe o contrário. Você pode substituir o padrão passando o parâmetro p_wallet_pathpara APEX_WEB_SERVICE. Se a carteira tiver uma senha (que não é necessária), você poderá passá-la com o parâmetro p_wallet_pwd.

OBS: Se você usa o Oracle OCI Autonomous ou APEX Services, não precisa se preocupar em criar uma carteira TLS de banco de dados. A Oracle cria uma carteira TLS para você e a preenche com quase todos os certificados SSL/TLS disponíveis.


Uma alternativa para uma carteira de banco de dados é usar um servidor proxy. Com essa abordagem, você chama um terminal HTTP e o proxy de encaminhamento passa a solicitação para o terminal final por HTTPS.

APEX_WEB_SERVICE permite especificar um proxy usando o parâmetro p_proxy_override.

A maioria dos serviços da web são seguros e exigem que você passe algumas credenciais para autenticar sua solicitação. APEX_WEB_SERVICE facilita o tratamento de credenciais. No centro dessa facilidade de uso estão as credenciais da Web APEX . As credenciais da Web APEX oferecem uma maneira de armazenar suas credenciais com segurança, facilitando o consumo de serviços APEX como APEX_WEB_SERVICE. As credenciais da Web APEX suportam os seguintes tipos de credenciais:

  • Autenticação Básica - Envia nome de usuário e senha no formato codificado em Base64 como o cabeçalho da solicitação de autorização.

  • Credenciais do cliente OAuth2 - O Oracle APEX troca o ID do cliente e o segredo do cliente por um token de acesso usando uma URL de servidor de token. O token de acesso é então usado para executar a solicitação real. Se o token de acesso expirar, o Oracle APEX solicitará um novo de forma transparente.

  • Autenticação Nativa OCI - O Oracle APEX assina solicitações para a API REST do Oracle Cloud Infrastructure (OCI), conforme descrito na Documentação do OCI.

  • Cabeçalho HTTP – A credencial é adicionada à solicitação REST como um cabeçalho HTTP. O nome da credencial é usado como nome do cabeçalho e o segredo da credencial é usado como valor do cabeçalho.

  • String de consulta de URL – A credencial é adicionada à URL da solicitação REST como um parâmetro de string de consulta (por exemplo: ?name=value).

  • Par de chaves - Uma credencial de par de chaves consiste em uma chave pública, compartilhada abertamente para criptografar dados, e uma chave privada, mantida em segredo com segurança para descriptografar dados, garantindo uma troca segura de dados.

Para utilizar uma credencial da Web APEX em sua chamada de serviço da Web, você precisa fazer referência ao ID estático da credencial da Web no p_credential_static_idparâmetro (veja os exemplos abaixo).

Depois de chamar um serviço da web usando APEX_WEB_SERVICE, você precisará confirmar se funcionou. No mundo das APIs REST, isso é feito verificando o código de status da resposta HTTP. Embora existam diretrizes sobre o significado de cada código de resposta, você precisa entender os códigos de resposta de cada API chamada. Um código de resposta por si só não diz tudo. Algumas APIs podem retornar uma 500resposta e fornecer detalhes do erro na carga útil da resposta.

Para obter o código de resposta de uma chamada para APEX_WEB_SERVICE, você deve verificar o pacote PL/SQL global apex_web_service.g_status_code.

  l_response_clob := 
    apex_web_service.make_rest_request
     (p_url         => l_rest_url,
      p_http_method => 'GET');

  IF apex_web_service.g_status_code != 200 THEN
    -- Algo deu errado. Adicione o código aqui para lidar com o erro.
  END IF;

Ao chamar serviços da web, você deve especificar um método HTTP. Os métodos HTTP possíveis são HTTP GET, POST, PUT, DELETE e PATCH. Ao usar APEX_WEB_SERVICE, você seleciona o método usando o p_http_methodparâmetro. O padrão APEX_WEB_SERVICE é o método GET se você não o fornecer explicitamente.

OBS: É uma boa prática sempre especificar um valor para p_http_method. Isso deixa as coisas claras para o próximo desenvolvedor que visualizar seu código.

Todas as chamadas para a APEX_WEB_SERVICEAPI são registradas na tabela apex_webservice_logVocê pode visualizar os logs clicando em Monitorar atividade > Log de atividades de serviço da Web no APEX Builder.


Você pode controlar se as chamadas para APEX_WEB_SERVICE são registradas nas configurações do espaço de trabalho:


Depois de configurar um novo ambiente APEX e começar a fazer muitas chamadas para APEX_WEB_SERVICE, muitas pessoas recebem a mensagem de erro " ORA-20001: Você excedeu o número máximo de solicitações de serviços web por espaço de trabalho".

Isso ocorre porque, por padrão, o APEX está configurado para permitir apenas 1.000 solicitações de serviços da Web em um período de 24 (janela contínua).

Você pode alterar isso no nível do espaço de trabalho ou no espaço de trabalho INTERNO (serviços de administração) para alterá-lo para toda a instância. A configuração do valor no nível da área de trabalho substitui o valor definido no nível INTERNO (Serviços de Administração).

OBS: Se ainda não o fez, aconselho que altere o padrão INTERNO (Serviços de Administração) o mais rápido possível.


Nível de Serviços Internos/Administrativos

Faça login no espaço de trabalho INTERNO (Serviços de Administração) e clique em Gerenciar instância > Segurança > Isolamento do espaço de trabalho > 'Máximo de solicitações de serviço da Web'.



Faça login no espaço de trabalho INTERNO (Serviços de Administração) e clique em Gerenciar Espaços de Trabalho > Espaços de Trabalho Existentes > Editar Informações do Espaço de Trabalho > Isolamento do Espaço de Trabalho.



OBS: A opção de substituição do espaço de trabalho não está disponível para os serviços OCI ATP ou APEX.


Definir via API

Dica bônus: você também pode definir o máximo de solicitações de serviço da Web para um espaço de trabalho usando a apex_instance_adminAPI PL/SQL.

BEGIN
  apex_instance_admin.set_workspace_parameter
   (p_workspace => 'ABC',
    p_parameter => 'MAX_WEBSERVICE_REQUESTS' ,
    p_value     => 10000000);
    COMMIT;
END;


Cabeçalhos de resposta

O conceito final que precisamos abordar são os cabeçalhos de resposta. Os serviços da Web geralmente incluem cabeçalhos HTTP na resposta, fornecendo informações adicionais, como eTag e informações de tipo de conteúdo . Depois de chamar APEX_WEB_SERVICE, o APEX preenche um array PL/SQL chamado apex_web_service.g_headers contendo uma lista de cabeçalhos HTTP de resposta.

-- Buscando os cabeçalhos de resposta HTTP após chamar apex_web_service

FOR i in 1.. apex_web_service.g_headers.count LOOP
  dbms_output.put_line
   ('Name: ' || apex_web_service.g_headers(i).name ||
    'Value: ' || apex_web_service.g_headers(i).value);
END LOOP;


Casos de uso

Agora que cobrimos os conceitos, vamos examinar os exemplos. Esta seção revisará vários exemplos de chamada de APIs REST usando APEX_WEB_SERVICE. Esses exemplos se concentrarão em apex_web_service.make_rest_request e apex_web_service.make_rest_requestb.


Chamada simples de API REST

Na sua forma mais simples, você pode ligar apex_web_service.make_rest_requestda seguinte maneira. Esta API REST específica não requer autenticação.

DECLARE
  l_response      CLOB;
BEGIN
  l_response := apex_web_service.make_rest_request
   (p_url         => 'https://official-joke-api.appspot.com/random_joke',
    p_http_method => 'GET');
  dbms_output.put_line('Response Code   : ' || apex_web_service.g_status_code);
  dbms_output.put_line('Response Payload: ' || l_response);
END;

-- Resultado
Response Status : 200
Response Payload: {"type":"general","setup":"Why did Sweden start painting barcodes on the sides of their battleships?","punchline":"So they could Scandinavian.","id":318}

A instrução CURL equivalente é semelhante a esta:

curl --location 'https://official-joke-api.appspot.com/random_joke'


Autenticação Básica

Esta solicitação chama um serviço web que possui autenticação básica (nome de usuário e senha):

DECLARE
  l_response      CLOB;
BEGIN
  -- Define os cabeçalhos HTTP da requisição.
  apex_web_service.set_request_headers 
   (p_name_01  => 'Content-Type', 
    p_value_01 => 'application/json',
    p_reset    => TRUE); 

  -- Chama a API usando Username e Password.
  l_response := apex_web_service.make_rest_request 
    (p_url                  => 'https://dummyjson.com/auth/login', 
     p_http_method          => 'POST', 
     p_transfer_timeout     => 10, 
     p_username             => 'Jon', 
     p_password             => 'ABCDEF',
     p_scheme               => 'Basic'); 

  dbms_output.put_line('Response Status : ' || apex_web_service.g_status_code);
  dbms_output.put_line('Response Payload: ' || l_response);
END;
  • APEX_WEB_SERVICE cuida da codificação em Base 64 do nome de usuário e senha e do envio de um cabeçalho HTTP semelhante a Authorization: Basic bmxvaXRlcnRvbjg6SFRReHhYVjlCcTQ=.
    • A instrução CURL equivalente é semelhante a esta:

      curl --location --request POST 'https://dummyjson.com/auth/login' \
      --header 'Content-Type: application/json' \
      --header 'Authorization: Basic bmxvaXRlcnRvbjg6SFRReHhYVjlCcTQ='

      Esta solicitação chama uma API do Microsoft Graph para obter uma lista de sites do SharePoint para o locatário do Microsoft Office 365.

      DECLARE
        l_response      CLOB;
        lt_parm_names   apex_application_global.VC_ARR2; 
        lt_parm_values  apex_application_global.VC_ARR2; 
      BEGIN

        -- Configura os cabeçalhos HTTP da requisição.
        --  p_reset limpa qualquer cabeçalho HTTP de uma chamada anterior.
        apex_web_service.set_request_headers 
         (p_name_01  => 'Prefer', 
          p_value_01 => 'apiversion=2.1',
          p_reset    => TRUE); 

        -- Define os parâmetros da string da consulta
        lt_parm_names(1)  := '$select'; 
        lt_parm_values(1) := 'name,displayName,sharepointIds,siteCollection'; 
        lt_parm_names(2)  := '$top'; 
        lt_parm_values(2) := '2'; 

        -- Chama a REST API.
        l_response := apex_web_service.make_rest_request 
          (p_url                  => 'https://graph.microsoft.com/v1.0/sites', 
           p_http_method          => 'GET', 
           p_transfer_timeout     => 10, 
           p_parm_name            => lt_parm_names, 
           p_parm_value           => lt_parm_values, 
           p_token_url            => 'https://login.microsoftonline.com/<OFFICE_TENANT_ID>/oauth2/v2.0/token', 
           p_credential_static_id => 'CN_MS_GRAPH_ACCESS'); 
        dbms_output.put_line('Response Status : ' || apex_web_service.g_status_code);
        dbms_output.put_line('Response Payload: ' || l_response);
      END;

      • p_transfer_timeout faz com que a solicitação atinja o tempo limite se não for concluída em 10 segundos.

      • p_token_url informa ao apex_web_service o URL a ser usado ao trocar o ID do cliente OAuth2 e o segredo do cliente por um token.

      Uma das muitas vantagens do APEX_WEB_SERVICE é que ele lida automaticamente com tokens OAuth2. Quando você chama APEX_WEB_SERVICE pela primeira vez, ele recebe um token e o armazena. Ele reutilizará esse token até que expire, quando então receberá automaticamente um novo. A troca de tokens acontece perfeitamente para você, como desenvolvedor.
      • p_credential_static_id informa ao APEX qual credencial Web APEX usar ao realizar a troca de tokens de credenciais do cliente OAuth2.

      O CURL para a busca do token OAuth2 que o APEX cuida para uso nos bastidores é assim:

      curl --location 'https://login.microsoftonline.com/<TBDOFFICETENANTID>/oauth2/v2.0/token' \
      --header 'Content-Type: application/x-www-form-urlencoded' \
      --data-urlencode 'grant_type=client_credentials' \
      --data-urlencode 'client_id=12345' \
      --data-urlencode 'client_secret=ABCDEF' \
      --data-urlencode 'scope=https://graph.microsoft.com/.default'

      O CURL para chamar a API MS Graph usando o token é semelhante a este:

      curl --location 'https://graph.microsoft.com/v1.0/sites?%24top=2&%24select=name%2CdisplayName%2CsharepointIds%2CsiteCollection' \
      --header 'Content-Type: application/x-www-form-urlencoded' \
      --header 'Prefer: apiversion=2.1' \
      --header 'Authorization: Bearer eyJ0eXA...'

      A credencial da Web para o exemplo acima é semelhante a esta:



      Chamada multiparte

      APEX_WEB_SERVICE oferece suporte a chamadas de API multiparte desde o APEX 20.2. Aqui está um exemplo de uma solicitação com várias partes.

      DECLARE
        -- Variável usada para construir a solicitação Multipart.
        l_multipart      apex_web_service.t_multipart_parts; 
        l_multipart_blob BLOB;
        l_file_blob      BLOB;
        l_response       CLOB;
      BEGIN

        -- Define o token OUath2 manualmente.
        -- apex_web_service definirá um cabeçalho HTTP chamado 'Autorização' para
         -- Portador {Valor do Token}
        apex_web_service.oauth_set_token(p_token => '{Token Value}');

        -- Adiciona o ID da unidade do SharePoint.
        apex_web_service.append_to_multipart 
         (p_multipart    => l_multipart, 
          p_name         => 'sharepoint_drive_id', 
          p_content_type => 'text/plain', 
          p_body         => 'ABC'); 

        -- Adicione o ID do item de arquivo do SharePoint.
        apex_web_service.append_to_multipart 
         (p_multipart    => l_multipart, 
          p_name         => 'sharepoint_item_id', 
          p_content_type => 'text/plain', 
          p_body         => 'ABC'); 

        -- Adicionar conteúdo do arquivo BLOB.
        apex_web_service.append_to_multipart 
         (p_multipart    => l_multipart, 
          p_name         => 'file', 
          p_filename     => 'Test_File.pdf', 
          p_content_type => 'application/pdf', 
          p_body_blob    => l_file_blob); 

        -- Cria a solicitação multipart completa como um BLOB.
        l_multipart_blob := apex_web_service.generate_request_body 
                             (p_multipart => l_multipart); 

        -- Posta o BLOB Multipart na API REST.
        -- Chamando apex_web_service.oauth_set_token acima, significa
        -- não precisamos passar uma credencial da Web.
        l_response := apex_web_service.make_rest_request 
         (p_url         => 'https://www.example.com', 
          p_http_method => 'POST', 
          p_body_blob   => l_multipart_blob);  

        dbms_output.put_line('Response Status : ' || apex_web_service.g_status_code);
        dbms_output.put_line('Response Payload: ' || l_response);
      END;

      • No exemplo acima, estou usando um método alternativo para definir o token OAuth chamando apex_web_service.oauth_set_token.

      Freqüentemente, você precisa buscar mídia, em vez de JSON ou XML. Neste exemplo, estou buscando um arquivo do SharePoint.

      -- Buscar um BLOB do SharePoint
      DECLARE
        l_file_blob     BLOB;
        l_sp_drive_id   VARCHAR2(100) := '<SHAREPOINT_DRIVE_ID>';
        l_sp_file_id    VARCHAR2(100) := '<SHAREPOINT_ITEM_ID>';
        l_url           VARCHAR2(32000);
      BEGIN

        -- Define os cabeçalhos HTTP da solicitação.
        apex_web_service.set_request_headers 
         (p_name_01  => 'Prefer', 
          p_value_01 => 'apiversion=2.1',
          p_reset    => TRUE); 

        -- Crie a URL para o arquivo usando a ID da unidade do SharePoint e a ID do arquivo.
        l_url := 'https://graph.microsoft.com/v1.0/drives/' || 
                   l_sp_drive_id || '/items/' || l_sp_file_id || '/content';

        -- Chame a API SharePoint MS Graph para buscar o arquivo em uma variável BLOB.
        l_file_blob := apex_web_service.make_rest_request_b 
          (p_url                  => l_url, 
           p_http_method          => 'GET', 
           p_transfer_timeout     => 25,
           p_token_url            => 'https://login.microsoftonline.com/<OFFICE_TENANT_ID>/oauth2/v2.0/token',
           p_credential_static_id => 'CN_MS_GRAPH_ACCESS'); 

        dbms_output.put_line('Response Status : ' || apex_web_service.g_status_code);
        dbms_output.put_line('File Size       : ' || 
          apex_string_util.to_display_filesize(p_size_in_bytes => dbms_lob.getlength(l_file_blob)));
      END;

      -- Result:
      -- Response Status : 200
      -- File Size       : 11.4KB

      OBS: APEX_WEB_SERVICE torna a busca de um arquivo do SharePoint muito fácil. Depois de definir uma credencial da Web, precisamos de apenas três linhas de código para buscar um arquivo.


      Obtenha um feed de blog XML Atom

      Podemos alcançar grandes resultados se combinarmos APEX_WEB_SERVICE com outros recursos do banco de dados Oracle. Digamos que queremos consultar as últimas cinco postagens do feed do blog de Jeff Smith. As postagens do blog de Jeff estão disponíveis por meio de um feed RSS baseado em XML, acessível usando o URL https://www.thatjeffsmith.com/feed/atom . Não há segurança; você pode copiar e colar o URL acima em seu navegador e ver o feed.


      Podemos transformar esse feed em linhas e colunas que podemos consumir no APEX usando o seguinte SQL:

      SELECT TO_UTC_TIMESTAMP_TZ(bp.date_published)  date_published
      ,      TO_UTC_TIMESTAMP_TZ(bp.date_updated)    date_updated
      ,      bp.guid
      ,      bp.title
      ,      bp.author
      ,      NVL(bp.link, bp.link_alt) link
      ,      bp.description
      ,      bp.content
      FROM   XMLTABLE(XMLNAMESPACES('http://www.w3.org/2005/Atom' AS "ns0"), 'ns0:feed/ns0:entry'
              PASSING XMLTYPE(apex_web_service.make_rest_request
                               (p_url => 'https://www.thatjeffsmith.com/feed/atom', 
                                p_http_method => 'GET'))
              COLUMNS
                guid           VARCHAR2(255)  PATH 'ns0:id',
                date_published VARCHAR2(50)   PATH 'ns0:published',
                date_updated   VARCHAR2(50)   PATH 'ns0:updated',
                title          VARCHAR2(500)  path 'ns0:title',
                author         VARCHAR2(255)  path 'ns0:author/ns0:name',
                link           VARCHAR2(500)  path 'ns0:link[@rel eq "alternate"]/@href',
                link_alt       VARCHAR2(500)  path 'ns0:link[1]/@href', 
                description    VARCHAR2(500)  path 'ns0:summary',
                content        CLOB           path 'ns0:content'
          ) bp;
      • Olhando profundamente na cláusula FROM, você pode ver que estamos chamando apex_web_service.make_rest_request. Isso retorna o XML do feed para a função XMLTYPE, que converte o texto XML em um objeto XML.

      • Assim que tivermos um objeto XMLTYPE, podemos passá-lo para XMLTABLE, que mapeia o XML em linhas e colunas.

      • Neste ponto, você precisa fazer referência aos campos do feed que deseja expor na consulta SQL.

      OBS: Essa técnica pode transformar todos os tipos de dados em linhas e colunas. Você poderia usar JSON_TABLE para buscar e analisar JSON. Você pode até combinar outra API APEX PL/SQL APEX_ZIP , para buscar um arquivo JSON compactado, descompactá-lo, analisá-lo e transformá-lo em linhas e colunas em uma única instrução SQL. Case isso com APEX_DATA_PARSER e o mundo inteiro será sua ostra!


      Conclusão

      Embora eu tenha classificado esta postagem como o 'guia definitivo', tenho certeza de que há muitos casos de uso para APEX_WEB_SERVICE que perdi. Isso demonstra o poder e a flexibilidade desta API. Eu recomendo fortemente que você se familiarize com esta, minha API favorita do Oracle APEX PL/SQL!

      -------
      Fonte: John Dixon - Blog Cloud Nueva



      Nenhum comentário:

      Postar um comentário