Comunicação entre aplicativos¶
Este tópico descreve como um Snowflake Native App pode se comunicar com outro Snowflake Native App usando comunicação entre aplicativos (IAC).
Comunicação entre aplicativos: Visão geral¶
A comunicação entre aplicativos (IAC) permite que um Snowflake Native App forneça funcionalidade adicional a outros Snowflake Native Apps na mesma conta de consumidor, fornecendo acesso a funções e procedimentos que outros aplicativos podem chamar.
Por exemplo, um Snowflake Native App que resolve IDs do cliente pode ajudar outros Snowflake Native Apps a aprimorar os dados de clientes unindo conjuntos de dados de diferentes fornecedores.
IAC fornece infraestrutura para que dois ou mais aplicativos independentes se comuniquem entre si, respeitando suas necessidades de gerenciamento e segurança. Desenvolvedores de aplicativo habilitam IAC para o aplicativo fazendo o seguinte:
Criação interfaces.
Uso de funções de aplicativos para controlar o acesso às interfaces.
Interação síncrona ou assíncrona. A interação síncrona utiliza procedimentos armazenados ou funções que outros aplicativos podem chamar diretamente, enquanto a interação assíncrona fornece acesso para solicitar resultados que são armazenados em tabelas ou exibições, que outros aplicativos podem pesquisar para verificar resultados.
Terminologia¶
IAC utiliza os seguintes termos:
- Cliente
O aplicativo que inicia a solicitação de conexão e chama as funções e procedimentos do aplicativo servidor.
- Servidor
O aplicativo que fornece acesso às suas funções e procedimentos usando funções do aplicativo.
- Consumidor
O usuário que instala os aplicativos cliente e servidor.
- Configuração do aplicativo
Um objeto SQL que o app do cliente usa para solicitar o nome do app do servidor. IAC usa uma configuração de aplicativo do tipo
APPLICATION_NAMEpara armazenar o nome do app servidor.- Especificação do aplicativo
Um objeto SQL que o aplicativo cliente cria para solicitar uma conexão com o aplicativo do servidor. O IAC usa uma especificação de aplicativo do tipo
CONNECTION. Para mais informações sobre as especificações de aplicativo, consulte Visão geral das especificações do aplicativo.
Fluxo de trabalho para comunicação entre aplicativos¶
O estabelecimento e o uso de uma conexão envolve um processo de handshake entre o aplicativo cliente e o aplicativo servidor.
Obter nomes de funções de app do provedor de apps do servidor: o provedor de apps do cliente coordena-se com o provedor de apps do servidor fora do Snowflake para determinar quais funções de app do servidor solicitar na especificação de conexão.
Identificação do aplicativo de destino: O aplicativo cliente cria um objeto de definição de configuração para solicitar o nome do aplicativo servidor. O consumidor detecta as solicitações recebidas e fornece o nome do app do servidor para o app do cliente por meio do objeto de configuração.
Solicitação e aprovação de uma conexão: O aplicativo cliente cria uma especificação para solicitar uma conexão com o aplicativo servidor e o consumidor aprova a solicitação de conexão.
Comunicação com o aplicativo servidor: O aplicativo cliente chama os procedimentos ou as funções do aplicativo servidor.
Identificação do aplicativo de destino¶
Antes que um aplicativo cliente possa se comunicar com um aplicativo servidor, ele deve primeiro identificar o nome exato do aplicativo. Como o consumidor pode escolher um nome personalizado para um aplicativo durante a instalação, o aplicativo cliente deve primeiro identificar o nome exato do aplicativo servidor.
O script de configuração do aplicativo cliente cria um objeto CONFIGURATION DEFINITION para solicitar essas informações.
O exemplo a seguir mostra como o script de configuração do aplicativo cliente cria um objeto CONFIGURATION DEFINITION para solicitar o nome do aplicativo servidor:
ALTER APPLICATION
SET CONFIGURATION DEFINITION my_server_app_name_configuration
TYPE = APPLICATION_NAME
LABEL = 'Server App'
DESCRIPTION = 'Request for an app that will provide access to server procedures and functions. The server app version must be greater than or equal to 3.2.'
APPLICATION_ROLES = (my_server_app_role);
O exemplo a seguir mostra como o consumidor verifica as solicitações de definição de configuração recebidas:
SHOW CONFIGURATIONS IN APPLICATION my_server_app_name;
Esse comando retorna resultados semelhantes aos seguintes:
name | created_on | updated_on | type | ...
my_server_app_name_configuration | 2026-02-09 10:00:00.000 | 2026-02-09 10:00:00.000 | APPLICATION_NAME | ...
O consumidor então usa o seguinte comando para fornecer o nome do app do servidor:
ALTER APPLICATION my_client_app_name
SET CONFIGURATION my_server_app_name_configuration
VALUE = MY_SERVER_APP_NAME;
Solicitação e aprovação de uma conexão¶
Assim que o app do cliente tem o nome do app do servidor, ele cria uma APPLICATION SPECIFICATION para solicitar uma conexão com o app do servidor. Observe que os nomes das funções do aplicativo são obtidos por meio de comunicação offline fora do Snowflake.
O exemplo a seguir mostra como criar uma APPLICATION SPECIFICATION para uma conexão com o aplicativo servidor chamado my_server_app_name:
ALTER APPLICATION SET SPECIFICATION my_server_app_name_connection_specification
TYPE = CONNECTION
LABEL = 'Server App'
DESCRIPTION = 'Request for an app that will provide access to server procedures and functions. The server app version must be greater than or equal to 3.2.'
SERVER_APPLICATION = MY_SERVER_APP_NAME -- server name obtained from Step 1
SERVER_APPLICATION_ROLES = (my_server_app_role);
Ao criar a especificação, o aplicativo cliente está solicitando que receba as funções do aplicativo servidor definidas na especificação do aplicativo.
Nota
Os valores fornecidos para LABEL e DESCRIPTION na especificação do aplicativo deve corresponder aos valores fornecidos para LABEL e DESCRIPTION no objeto CONFIGURATION DEFINITION criado na Etapa 1. Se os valores não corresponderem, a conexão não será exibida corretamente na Snowsight.
Para criar um fluxo de trabalho de conexão eficiente, recomendamos que o app do cliente crie a especificação do aplicativo no retorno de chamada síncrono before_configuration_change. Esse retorno de chamada é executado com o comando ALTER APPLICATION SET CONFIGURATION VALUE. Para informações sobre retornos de chamada, consulte Retornos de chamada. Para obter um exemplo de script de configuração que cria a especificação do aplicativo no retorno de chamada síncrono before_configuration_change, consulte Exemplos.
Assim que o app do cliente criar a especificação do aplicativo, o consumidor poderá revisar e aprovar ou recusar a solicitação de conexão.
Aprovação da solicitação de conexão usando SQL¶
O exemplo a seguir mostra como o consumidor aprova a solicitação de conexão usando SQL:
ALTER APPLICATION my_server_app_name
APPROVE SPECIFICATION my_server_app_name_connection_specification
SEQUENCE_NUMBER = 1;
Aprovação da solicitação de conexão usando Snowsight¶
Para visualizar e aprovar solicitações de conexão na Snowsight, faça o seguinte:
Faça login no Snowsight.
Selecione o aplicativo. Uma seção intitulada Application connections aparece abaixo de Configurations. Cada conexão pendente mostra o nome ou rótulo da conexão, uma breve descrição da conexão e um botão Review.
Clique no botão Review. Os detalhes da solicitação de conexão são exibidos.
Selecione o aplicativo de destino em Select from your apps.
Clique em Next. As seguintes informações são exibidas:
Um diagrama mostra que o app do cliente se conectará ao app do servidor e quais funções os apps usarão.
Os detalhes da conexão.
Um subconjunto das permissões do servidor que serão concedidas ao app do cliente. Para obter mais informações sobre considerações de segurança paraIAC, consulte:ref:
label-native_apps_iac_security_considerations.Um botão seletor Approve Connection. O botão está definido como On.
Para aprovar a conexão, deixe o botão seletor definido como On e clique em Save. A lista atualizada é exibida mostrando o status da conexão.
Para recusar a conexão, alterne o seletor para Off.
Para sair da página de revisão sem aprovar ou recusar a conexão, clique no botão Cancel.
Pós-aprovação¶
Quando o consumidor aprova a solicitação de conexão, o Snowflake Native App Framework concede as funções solicitadas do aplicativo servidor ao aplicativo cliente. A aprovação também concede USAGE no aplicativo cliente para o aplicativo servidor. Isso permite que o aplicativo servidor esteja ciente de quais aplicativos cliente estão conectados a ele.
Quando o consumidor aprova a solicitação de conexão, os seguintes retornos de chamada são acionados nos aplicativos cliente e servidor, respectivamente:
after_server_connection_change é acionado no app do cliente
after_client_connection_change é acionado no app do servidor
Esses retornos de chamada permitem que o servidor e o aplicativo cliente executem ações adicionais quando a conexão for estabelecida.
Para mais informações sobre como aprovar especificações de aplicativos, consulte os seguintes tópicos:
Comunicações com o aplicativo servidor¶
Depois que a conexão for estabelecida e o aplicativo cliente receber as funções solicitadas do aplicativo servidor, o aplicativo cliente poderá se comunicar com o aplicativo servidor.
Nota
Antes de chamar os métodos do aplicativo servidor, o aplicativo cliente deve recuperar o nome do aplicativo servidor em tempo de execução da especificação do aplicativo aprovado, para garantir que ele use o nome correto caso o aplicativo servidor seja renomeado. O exemplo a seguir mostra como recuperar o nome do aplicativo servidor no tempo de execução:
SHOW APPROVED SPECIFICATIONS ->>
SELECT PARSE_JSON("definition"):"SERVER_APPLICATION"::STRING
FROM $1
WHERE "name" = 'MY_SERVER_APP_NAME_CONNECTION_SPECIFICATION';
O aplicativo cliente pode se comunicar com o aplicativo servidor de forma síncrona ou assíncrona.
A comunicação síncrona envolve invocar diretamente os procedimentos ou funções do aplicativo servidor.
A comunicação assíncrona envolve o uso de uma fila armazenada em um objeto de dados, como uma tabela. Por exemplo, o aplicativo servidor pode fornecer um procedimento para inserir registros em uma tabela como solicitações, que o aplicativo servidor processa periodicamente. O aplicativo cliente pode então usar um procedimento diferente fornecido pelo servidor para verificar a tabela em busca de resultados.
O exemplo de operação síncrona a seguir mostra um aplicativo cliente chamando o procedimento de um aplicativo servidor usando Python:
session.call("server_app_name.customer_schema.get_customer_data", customer_id);
O exemplo de operação assíncrona a seguir mostra um aplicativo cliente chamando o procedimento de um aplicativo servidor usando Python. O aplicativo cliente chama o procedimento do aplicativo servidor, criando uma solicitação em uma tabela que é processada pelo aplicativo servidor. O aplicativo cliente pode pesquisar a tabela para verificar os registros atualizados com os resultados.
session.call("server_app_name.customer_schema.request_customer_data_async", customer_id);
O aplicativo cliente pode então pesquisar a tabela para verificar registros atualizados com os resultados:
session.call("server_app_name.customer_schema.check_customer_data_requests_async", customer_id);
Gerenciamento de conexões¶
Para visualizar as conexões existentes na Snowsight, faça o seguinte:
Faça login no Snowsight.
No menu de navegação, selecione Catalog » Apps.
Selecione o aplicativo. Todas as conexões do aplicativo são mostradas em uma seção chamada Configurations. Abaixo dessa seção, há uma subseção com o nome Application connections.
Para modificar uma conexão, clique no ícone de lápis. Você pode alterar o seguinte:
Qual aplicativo está conectado ao aplicativo
O status de aprovação da conexão
Para visualizar o aplicativo conectado, clique no botão View app.
Para alterar as configurações de segurança da conexão, clique no ícone de engrenagem.
Considerações de segurança¶
Ao aprovar uma solicitação de especificação, os consumidores devem estar cientes de que permitir que o aplicativo cliente acesse o aplicativo servidor pode aumentar os privilégios do aplicativo cliente. Por exemplo, se um aplicativo servidor tiver acesso externo, o aplicativo cliente poderá obter acesso indireto à Internet ou a outros recursos externos por meio do aplicativo servidor. Se o aplicativo servidor for um aplicativo cliente de outro aplicativo servidor, o aplicativo cliente poderá acessar os recursos do outro aplicativo servidor por meio do primeiro aplicativo servidor.
Os consumidores devem inspecionar os recursos e privilégios do aplicativo servidor antes de aprovar uma conexão. Use uma função de administrador (por exemplo, ACCOUNTADMIN) para inspecionar os recursos do servidor. Inspecionar o servidor com uma função com privilégios inferiores não revelará todos os recursos e privilégios do servidor. Os consumidores devem observar que o código do app do servidor não é visível para o consumidor e que as permissões e recursos do app do servidor podem ser alterados depois que o consumidor aprovar a conexão.
Alguns exemplos de comandos SQL para inspecionar os recursos e privilégios do aplicativo servidor incluem, mas não estão limitados a:
SHOW GRANTS TO APPLICATION: esse comando lista quais concessões no aplicativo cliente foram concedidas ao aplicativo servidor.
SHOW PRIVILEGES IN APPLICATION: esse comando lista quais possíveis privilégios no nível da conta poderiam ser concedidos ao aplicativo cliente.
SHOW REFERENCES IN APPLICATION: esse comando lista referências que o aplicativo cliente poderia usar sem concessões.
SHOW SPECIFICATIONS IN APPLICATION: esse comando lista as especificações do aplicativo que o consumidor aprovou, incluindo integrações de acesso externo (EAIs), integrações de segurança, compartilhamentos, listagens e conexões.
Referência de SQL¶
Os seguintes comandos SQL são usados para gerenciar a comunicação entre aplicativos.
ALTER APPLICATION SET SPECIFICATION: Cria uma especificação de aplicativo que o aplicativo servidor usa para permitir que o aplicativo cliente tenha acesso às suas funções e procedimentos.
ALTER APPLICATION DROP SPECIFICATION: exclui uma especificação do aplicativo.
ALTER APPLICATION … { APPROVE | DECLINE} SPECIFICATION: aprova ou rejeita uma solicitação de especificação de app.
SHOW SPECIFICATIONS: lista todas as especificações em um aplicativo.
DESCRIBE SPECIFICATION: descreve as especificações de um aplicativo para outro.
ALTER APPLICATION SET CONFIGURATION DEFINITION: cria ou atualiza uma configuração de aplicativo (um par chave-valor) que solicita o nome de outro aplicativo do consumidor.
ALTER APPLICATION DROP CONFIGURATION DEFINITION: exclui uma configuração do aplicativo.
ALTER APPLICATION SET CONFIGURATION VALUE: define um valor em uma configuração do aplicativo.
ALTER APPLICATION UNSET CONFIGURATION: desativa o valor da configuração do aplicativo especificado.
SHOW CONFIGURATIONS: lista todas as configurações em um aplicativo.
DESCRIBE CONFIGURATION: descreve os detalhes de uma configuração de aplicativo.
IS_CONFIGURATION_SET (função SYS_CONTEXT): retorna se a configuração tem ou não um valor definido.
GET_CONFIGURATION_VALUE (função SYS_CONTEXT): retorna o valor atual da configuração.
SHOW GRANTS TO APPLICATION: lista todos os privilégios e funções de banco de dados/aplicativos concedidos ao aplicativo especificado.
SHOW GRANTS TO APPLICATION ROLE: lista todas as permissões que a função de aplicativo possui.
SHOW GRANTS OF APPLICATION ROLE: lista todas as funções e aplicativos que tenham a função de aplicativo especificada.
Retornos de chamada¶
O Snowflake Native App Framework fornece retornos de chamada de ciclo de vida para ajudar a gerenciar o fluxo de trabalho de comunicação entre apps. Esses retornos de chamada permitem que um app reaja a alterações em configurações, conexões e especificações. Para usar retornos de chamada, registre-os na seção lifecycle_callbacks do arquivo de manifesto do app.
Para obter informações gerais sobre retornos de chamada, consulte Retornos de chamada.
Retornos de chamada de configuração¶
Esses retornos de chamada são acionados quando um valor de configuração é definido ou removido. Um caso de uso comum é usar o retorno de chamada before_configuration_change para criar automaticamente uma especificação de conexão quando o consumidor fornece o nome do app do servidor.
- validate_configuration_change
Um retorno de chamada síncrono chamado como parte do comando
ALTER APPLICATION SET CONFIGURATION VALUE. Permite que o app execute validação personalizada no valor fornecido. Se o retorno de chamada retornar um erro, o comando falhará e o novo valor não será definido.- before_configuration_change
Um retorno de chamada síncrono chamado como parte dos comandos
ALTER APPLICATION SET CONFIGURATION VALUEeALTER APPLICATION UNSET CONFIGURATION. Permite que o app execute operações com base no valor da configuração antes que ele seja salvo.- after_configuration_change
Um retorno de chamada assíncrono chamado após a conclusão dos comandos
ALTER APPLICATION SET CONFIGURATION VALUEouALTER APPLICATION UNSET CONFIGURATION. Permite que o app reaja à alteração, por exemplo, para fins de notificação ou rastreamento.
Retornos de chamada de conexão¶
Esses retornos de chamada são acionados quando o status de uma conexão muda, como quando uma conexão é estabelecida, recusada, encerrada ou quando o app conectado é excluído.
- after_server_connection_change
Um retorno de chamada assíncrono acionado no app do cliente por qualquer operação que impacte o estado da conexão, incluindo aprovação, recusa ou descarte de uma especificação ou descarte do app do servidor.
- after_client_connection_change
Um retorno de chamada assíncrono acionado no app do servidor por qualquer operação que impacte o estado da conexão, incluindo aprovação, recusa ou descarte de uma especificação ou descarte do app do cliente.
- after_server_version_change
Um retorno de chamada assíncrono chamado no app do cliente após a alteração da versão ou do número de patch do app do servidor. Permite que o app do cliente reaja a uma atualização ou downgrade.
Exemplos¶
Os exemplos a seguir mostram como configurar a comunicação entre aplicativos.
Exemplo: Script de configuração e arquivos de manifesto¶
O exemplo a seguir mostra o script de configuração de um aplicativo cliente (setup.sql):
CREATE OR ALTER VERSIONED SCHEMA app_schema;
-- create a callback that creates the connection request before the config value of the server name is saved
CREATE OR REPLACE PROCEDURE app_schema.before_config_change_callback(config_name STRING, config_value STRING)
RETURNS STRING
LANGUAGE SQL
AS
$$
DECLARE
spec_name VARCHAR;
existing_target VARCHAR;
BEGIN
IF (config_value IS NOT NULL AND config_name = 'MY_SERVER_APP_NAME_CONFIGURATION') THEN
SHOW SPECIFICATIONS;
SELECT PARSE_JSON("definition"):SERVER_APPLICATION::STRING
INTO existing_target
FROM TABLE(RESULT_SCAN(LAST_QUERY_ID()));
IF(existing_target IS NOT NULL AND UPPER(existing_target) != UPPER(config_value)) THEN
EXECUTE IMMEDIATE 'ALTER APPLICATION DROP SPECIFICATION CONNECTION_' || UPPER(existing_target);
END IF;
spec_name := 'CONNECTION_' || UPPER(config_value);
EXECUTE IMMEDIATE
'ALTER APPLICATION SET SPECIFICATION ' || spec_name || '
TYPE = CONNECTION
LABEL = ''Server App''
DESCRIPTION = ''Request for an app that will provide access to server procedures and functions. The server app version must be greater than or equal to 3.2.''
SERVER_APPLICATION = ' || config_value || '
SERVER_APPLICATION_ROLES = (my_server_app_role)';
END IF;
RETURN 'success';
END;
$$;
CREATE APPLICATION ROLE IF NOT EXISTS client_app_user;
GRANT USAGE ON SCHEMA app_schema TO APPLICATION ROLE client_app_user;
ALTER APPLICATION SET CONFIGURATION DEFINITION my_server_app_name_configuration
TYPE = APPLICATION_NAME
LABEL = 'Server App'
DESCRIPTION = 'Request for an application that will provide access to server procedures and functions. The server app version must be greater than or equal to 3.2'
APPLICATION_ROLES = (client_app_user);
O exemplo a seguir mostra o arquivo de manifesto de um aplicativo cliente (manifest.yml):
manifest_version: 2
artifacts:
setup_script: setup.sql
lifecycle_callbacks:
before_configuration_change: app_schema.before_config_change_callback
Pontos importantes sobre o exemplo de código anterior:
No retorno de chamada before_configuration_change, o app verifica se existe uma especificação de conexão correspondente ao valor anterior da configuração e a descarta, caso exista. O retorno de chamada cria uma nova especificação de conexão para o nome do aplicativo servidor recém-fornecido. Criar uma nova conexão quando o nome do servidor está definido evita especificações de conexão duplicadas.
Exemplo: Comunicação assíncrona entre apps¶
O exemplo a seguir mostra como criar procedimentos no script de configuração de um app do servidor (setup.sql) para comunicação assíncrona. O app do servidor cria uma tabela de fila de processamento e fornece dois procedimentos para apps do cliente por meio de uma função de app: submit_request para adicionar uma solicitação à fila e fetch_response para recuperar o resultado de uma solicitação concluída. O app do servidor usa periodicamente o procedimento process_requests para processar todas as solicitações pendentes.
CREATE TABLE IF NOT EXISTS app_schema.processing_queue (
request_id NUMBER AUTOINCREMENT,
operation STRING,
input STRING,
status STRING DEFAULT 'PENDING',
response STRING DEFAULT ''
);
CREATE OR REPLACE PROCEDURE app_schema.submit_request(operation STRING, input STRING)
RETURNS STRING
LANGUAGE SQL
EXECUTE AS OWNER
AS
$$
BEGIN
INSERT INTO app_schema.processing_queue (operation, input) VALUES (:operation, :input);
RETURN 'Request submitted successfully';
END;
$$;
CREATE OR REPLACE PROCEDURE app_schema.process_requests()
RETURNS STRING
LANGUAGE SQL
EXECUTE AS OWNER
AS
$$
DECLARE
-- Cursor to find all PENDING requests
c1 CURSOR FOR SELECT * FROM app_schema.processing_queue WHERE status = 'PENDING';
result STRING;
BEGIN
FOR request IN c1 DO
IF (request.operation = 'OPERATION_X') THEN
-- assuming there is a UDF func_x(input) to perform operation_x
result := (SELECT func_x(:request.input));
END IF;
-- update the processing queue with the result
LET stmt STRING :=
'UPDATE app_schema.processing_queue SET status = 'DONE', response = ' ||
result ||
' WHERE request_id = ' ||
request.request_id;
EXECUTE IMMEDIATE (:stmt);
END FOR;
RETURN 'Processed pending requests.';
END;
$$;
CREATE OR REPLACE PROCEDURE app_schema.fetch_response(operation STRING, input STRING)
RETURNS STRING
LANGUAGE SQL
EXECUTE AS OWNER
AS
$$
BEGIN
LET res STRING := (SELECT response FROM app_schema.processing_queue WHERE operation = :operation AND input = :input);
RETURN res;
END;
$$;
CREATE APPLICATION ROLE IF NOT EXISTS my_server_app_role;
GRANT USAGE ON SCHEMA app_schema TO APPLICATION ROLE my_server_app_role;
GRANT USAGE ON PROCEDURE app_schema.submit_request(string, string) TO APPLICATION ROLE my_server_app_role;
GRANT USAGE ON PROCEDURE app_schema.process_requests() TO APPLICATION ROLE my_server_app_role;
GRANT USAGE ON PROCEDURE app_schema.fetch_response(string, string) TO APPLICATION ROLE my_server_app_role;