APEX – Enviando arquivos para o Object Storage

O OCI Object storage possui uma funcionalidade muito legal chamada PAR (Pre-Authenticated Requests) que gera uma URL única e temporária que te permite interagir com buckets/objetos sem autenticação, então na prática você poderia ter um bucket privado e compartilhar os arquivos dele com quem quiser, pensando nisso e baseado nesse artigo aqui resolvi criar uma interface em APEX que recebe arquivos como uma caixa postal, a pessoa tem seu endereço (PAR) e te entrega o arquivo.

O PAR

Um PAR pode ser criado de diversas formas(console web, api, cli..) e com diversas opções:

Cada PAR precisa de um nome e de parâmetros de acesso, no nosso caso precisamos criar um do tipo Bucket com permissão de escrita (Permit Object writes), você também pode configurar um prazo de validade da URL, isso é muito util quando você quer compartilhar um arquivo com alguém e quer ter certeza que após determinado tempo o arquivo não esteja mais acessível.

Ao criar o PAR, copie a URL para uma localização segura pois ela só é exibida uma única vez!

APEX

Aqui no meu caso estou usando um APEX como serviço, mas você pode usar o que estiver a sua disposição, também no meu caso, optei por fazer uma aplicação pública(sem login) e para isso precisei alterar algumas opções, no workspace internal eu precisei ir em Manage Instance -> Security e habilitar a opção Allow Public File upload:

Após isso, criei meu Workspace(que aqui se chama upload) e criei uma página simples, tive que alterar a opção Authentication para public, lembrando que talvez no seu caso você não queira/precise fazer isso:

Esses são os meus componentes:

Basicamente precisamos de um objeto do tipo File Browse, um campo de texto(que vai receber nosso PAR) e um botão que vai juntar tudo isso em uma ação única.

File Browse

Esse objeto é bem simples, ele faz uma ponte entre um arquivo em sua máquina e uma tabela no banco do APEX, você pode criar uma tabela customizada para armazenar seus objetos, mas nesse caso estou usando a padrão que é a apex_application_temp_files, arraste esse recurso para a sua página, ele possui alguns modelos, aqui estou usando um que você arrasta os arquivos da sua máquina para ele, edite a seguinte opção para garantir que o objeto vá ser apagado logo após o envio:

Caso queira, você também pode adicionar algumas validações como tamanho máximo e formato de arquivo aceito, aqui no meu caso não alterei mais nada.

Campo texto

Aqui usei um objeto do tipo Text Field com o tipo URL

Marquei a opção Required para que fique uma mensagem informando que um valor precisa ser passado e também adicionei uma validação (no botão de upload) para caso ele esteja vazio que o upload não comece.

Botão de upload

Para esse botão usei a opção “Hot” com duas ações dinâmicas, uma que pega o valor do campo texto (P1_PAR) e faz o uso do apex_web_service para fazer a requisçao de envio e outra para validar se o campo texto possui um valor.

A de upload é do tipo submit page e tem a seguinte configuração:

Quando um evento do tipo Click acontecer no botão, ele vai fazer um submit page que tem o seguinte processo atrelado a ele:

O código que ele chama é o que está no tutorial de interação com o Object storage com algumas pequenas alterações, aqui por exemplo não fazemos autenticação e nossa URL vai ser passada pelo usuário:

declare
  l_request_url varchar2(32767);
  l_content_length number;

  l_response clob;
    
  upload_failed_exception exception;
begin
  for file in (
    select * from apex_application_temp_files
    where name = :P2_FILE
  ) loop
        l_request_url := :P1_PAR  || apex_util.url_encode(file.filename);
    apex_web_service.g_request_headers(1).name := 
      'Content-Type';
    apex_web_service.g_request_headers(1).value :=
      file.mime_type;
    l_response := apex_web_service.make_rest_request(
      p_url => l_request_url
      , p_http_method => 'PUT'
      , p_body_blob => file.blob_content
    );

    if apex_web_service.g_status_code != 200 then
      raise upload_failed_exception;
    end if;
  end loop;
delete from apex_application_temp_files where name = :P2_FILE;
end;

A parte importante desse código são as variáveis :P2_FILE (nome do nosso objeto File Browse) e :P1_PAR(nome do nosso campo de texto).

A validação se o campo texto possui valor é a seguinte:

Juntando tudo isso nós temos uma página bem simples :

Utilização

Crie um PAR com a opção  Permit object writes marcada:

Na página da aplicação no campo de texto coloque o seu PAR e selecione o arquivo:

Ao clicar em Upload ele já deve começar a ser enviado:

E o arquivo logo deve aparecer no bucket:

Caso a pessoa não entre o PAR, a nossa validação entra em vigor:

Bem pessoal, espero que tenham gostado dessa integração e espero que acompanhem a evolução dela pois ainda vou fazer algumas melhorias.

chevron_left
chevron_right