O SDK Java inclui uma biblioteca denominada API remota que lhe permite aceder de forma transparente aos serviços do App Engine a partir de qualquer aplicação Java. Por exemplo, pode usar a API Remote para aceder a um armazenamento de dados de produção a partir de uma app em execução na sua máquina local. Também pode usar a API Remote para aceder ao arquivo de dados de uma app do App Engine a partir de uma app do App Engine diferente.
Configurar a API remota no servidor
O componente de servidor da API remota é um servlet Java que faz parte do tempo de execução do App Engine para Java. Este servlet recebe pedidos do cliente da API Remote, envia-os para o serviço de back-end adequado e, em seguida, devolve o resultado da chamada de serviço ao cliente. Para instalar o servlet da API Remote, adicione o seguinte ao seu web.xml
:
O servlet devolve um erro se não existir um utilizador autenticado ou se o utilizador autenticado não for um administrador da sua aplicação, pelo que não é necessário configurar nenhuma segurança adicional. Depois de implementar a sua app com estas definições, qualquer app com o cliente da API Remote instalado pode usar os respetivos serviços. Isto inclui clientes Python que estão a usar a API Python Remote.
Configurar a API remota num cliente autónomo
Para configurar o componente de cliente da API Remote para utilização numa aplicação Java, adicione ${SDK_ROOT}/lib/impl/appengine-api.jar
e ${SDK_ROOT}/lib/appengine-remote-api.jar
ao seu classpath. Em seguida, no seu código, configure e instale a API Remote:
import com.google.appengine.tools.remoteapi.RemoteApiInstaller;
import com.google.appengine.tools.remoteapi.RemoteApiOptions;
// ...
RemoteApiOptions options = new RemoteApiOptions()
.server("[APP_ID].[REGION_ID].r.appspot.com", 443)
.useApplicationDefaultCredential();
RemoteApiInstaller installer = new RemoteApiInstaller();
installer.install(options);
// ... all API calls executed remotely
installer.uninstall();
O cliente da API Remote vai basear-se nas Credenciais padrão da aplicação que usam o OAuth 2.0.
Para executar uma credencial:
gcloud auth application-default login
Pode ligar-se facilmente a uma app do App Engine em execução localmente no servidor de desenvolvimento:
RemoteApiOptions options = new RemoteApiOptions()
.server("localhost", 8888) // server name must equal "localhost"
.useDevelopmentServerCredential();
Segue-se uma aplicação Java completa que, quando executada, insere uma entidade no arquivo de dados:
Configurar a API Remote num cliente do App Engine
Também pode usar a API Remote para aceder aos serviços de uma aplicação do App Engine
a partir de uma aplicação do App Engine diferente. Tem de adicionar
${SDK_ROOT}/lib/appengine-remote-api.jar
ao diretório WEB-INF/lib
e, em seguida, na app App Engine do cliente, configurar e instalar a API Remote tal como
fez no cliente Java autónomo.
Tenha em atenção que RemoteApiInstaller
só instala a API Remote no segmento que executa a instalação, por isso, tenha cuidado para não partilhar instâncias desta classe entre segmentos.
Usar a API Remote com o Maven
Para usar a funcionalidade da API Remote no seu projeto Maven, adicione as seguintes dependências
ao ficheiro pom.xml
do projeto:
Limitações e práticas recomendadas
O módulo remote_api esforça-se por garantir que, na medida do possível, se comporta exatamente como o datastore do App Engine nativo. Em alguns casos, isto significa fazer coisas que são menos eficientes do que poderiam ser de outra forma. Quando usar a API remote_api, tenha em atenção o seguinte:
Cada pedido de armazenamento de dados requer um processo de ida e volta
Uma vez que está a aceder ao arquivo de dados através de HTTP, existe um pouco mais de sobrecarga e latência do que quando acede localmente. Para acelerar o processo e diminuir a carga, tente limitar o número de viagens de ida e volta que faz agrupando as obtenções e as colocações, e obtendo lotes de entidades a partir de consultas. Este é um bom conselho não só para a remote_api, mas também para a utilização da base de dados em geral, porque uma operação em lote é considerada uma única operação da base de dados.
Pedidos de utilização da quota da remote_api
Uma vez que a remote_api opera através de HTTP, cada chamada de datastore que fizer incorre na utilização da quota para pedidos HTTP, bytes de entrada e saída, bem como na quota de datastore habitual. Tenha isto em atenção se estiver a usar a API remote_api para fazer atualizações em massa.
Aplicam-se limites da API de 1 MB
Tal como quando são executados nativamente, o limite de 1 MB nas solicitações e respostas da API continua a aplicar-se. Se as suas entidades forem particularmente grandes, pode ter de limitar o número de entidades que obtém ou coloca de cada vez para se manter abaixo deste limite. Infelizmente, isto entra em conflito com a minimização das viagens de ida e volta. Por isso, a melhor recomendação é usar os maiores lotes possíveis sem exceder as limitações de tamanho de pedidos ou respostas. No entanto, é improvável que isto seja um problema para a maioria das entidades.
Evite iterar consultas
Quando itera sobre consultas, o SDK obtém entidades do arquivo de dados em lotes de 20, obtendo um novo lote sempre que usa os existentes. Uma vez que cada lote tem de ser obtido num pedido separado pela API remote_api, não é possível fazê-lo de forma tão eficiente. Em alternativa, a API remote_api executa uma consulta totalmente nova para cada lote, usando a funcionalidade de deslocamento para obter mais resultados.
Se souber de quantas entidades precisa, pode fazer toda a obtenção num único pedido pedindo o número de que precisa.
Se não souber quantas entidades quer, pode usar cursores para iterar de forma eficiente em grandes conjuntos de resultados. Isto também permite evitar o limite de 1000 entidades imposto nas consultas normais da base de dados.
As transações são menos eficientes
Para implementar transações através da remote_api, acumula informações sobre entidades obtidas na transação, juntamente com cópias de entidades que foram colocadas ou eliminadas na transação. Quando a transação é confirmada, envia todas estas informações para o servidor do App Engine, onde tem de obter novamente todas as entidades que foram usadas na transação, verificar se não foram modificadas, colocar e eliminar todas as alterações feitas pela transação e confirmá-la. Se existir um conflito, o servidor reverte a transação e notifica o cliente, que tem de repetir todo o processo.
Esta abordagem funciona e duplica exatamente a funcionalidade fornecida pelas transações no arquivo de dados local, mas é bastante ineficiente. Use transações sempre que necessário, mas tente limitar o número e a complexidade das transações que executa para aumentar a eficiência.