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_NAME para 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.

  1. 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.

  2. 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.

  3. 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.

  4. 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);
Copy

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;
Copy

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;
Copy

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);
Copy

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;
Copy

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:

  1. Faça login no Snowsight.

  2. 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.

  3. Clique no botão Review. Os detalhes da solicitação de conexão são exibidos.

  4. Selecione o aplicativo de destino em Select from your apps.

  5. 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.

  6. 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.

  7. Para recusar a conexão, alterne o seletor para Off.

  8. 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:

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';
Copy

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);
Copy

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);
Copy

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);
Copy

Gerenciamento de conexões

Para visualizar as conexões existentes na Snowsight, faça o seguinte:

  1. Faça login no Snowsight.

  2. No menu de navegação, selecione Catalog » Apps.

  3. 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.

  4. 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

  5. Para visualizar o aplicativo conectado, clique no botão View app.

  6. 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.

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 VALUE e ALTER 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 VALUE ou ALTER 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);
Copy

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
Copy

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;
Copy