Página inicial do Docs → Serviços Atlas App
Funções do Atlas
Nesta página
GraphQL está obsoleto. Saiba mais.
Visão geral
Uma função do Atlas é um código JavaScript do lado do servidor que você escreve para definir o comportamento de sua aplicação. Você pode chamar as funções do seu aplicativo diretamente de uma aplicação de cliente ou definir serviços que integram e chamam funções automaticamente.
As funções podem chamar outras funções e incluir um cliente integrado para trabalhar com dados em clusters MongoDB Atlas. Elas também incluem utilitários globais úteis, suportam módulos integrados comuns do Node.js e podem importar e usar pacotes externos do registro npm.
exports = function(name) { return `Hello, ${name ?? "stranger"}!` }
As funções são sem servidor
Quando uma função é chamada, seu aplicativo encaminha a solicitação para um servidor de aplicativos gerenciado que avalia seu código e retorna o resultado. Esse modelo torna as funções sem servidor, o que significa que você não precisa implantar e gerenciar um servidor para executar o código. Em vez disso, você escreve o código-fonte da função e seu aplicativo lida com o ambiente de execução.
Funções têm contexto
Uma função é executada em um contexto que reflete seu ambiente de execução. O contexto inclui o usuário que chamou a função, como ele a chamou e o estado de sua aplicação quando a chamou. Você pode usar o contexto para executar código específico do usuário e trabalhar com outras partes de sua aplicação.
Para saber mais sobre como trabalhar com o contexto da função, consulte Contexto.
Quando usar as funções
As funções podem executar código JavaScript arbitrário definido por você, o que significa que você pode usá-las para quase tudo. Os casos de uso comuns incluem tarefas de baixa latência e execução curta, como movimentação de dados, transformações e validação. Você também pode usá-los para se conectar a serviços externos e abstrair os detalhes de implementação dos aplicativos clientes.
Além das funções que você invoca diretamente, você também escreve funções para vários serviços, como HTTPS endpoints, Atlas Triggers e resolvedores personalizados do GraphQL (o GraphQL está obsoleto, saiba mais). Esses serviços chamam automaticamente as funções para lidar com evento específicos. Por exemplo, sempre que um trigger de banco de dados observa um evento de alteração, ele chama sua função associada com o evento de alteração como argumento. Na função de trigger, é possível acessar as informações do evento de alteração e responder adequadamente.
Dica
Como escrever uma função
O código de uma função é essencialmente um arquivo de código-fonte JavaScript nomeado
, o que significa que você pode definir várias funções JavaScript em um único
arquivo de função. O arquivo deve exportar uma única função JavaScript para
servir como ponto de entrada para as chamadas recebidas. Quando você chama uma função por nome, você está realmente chamando a função JavaScript atribuída a exports
no arquivo de origem da função.
Por exemplo, aqui está uma função simples que aceita um argumento name
, adiciona uma mensagem de registro e retorna uma saudação para o nome fornecido:
exports = function Hello(name) { console.log(`Said hello to ${name}`); return `Hello, ${name}!`; };
Você pode usar a sintaxe JavaScript moderna e importar pacotes para definir funções mais complexas:
// You can use ES6 arrow functions const uppercase = (str) => { return str.toUpperCase(); }; // You can use async functions and await Promises exports = async function GetWeather() { // You can get information about the user called the function const city = context.user.custom_data.city; // You can import Node.js built-ins and npm packages const { URL } = require("url"); const weatherUrl = new URL("https://example.com"); weatherUrl.pathname = "/weather"; weatherUrl.search = `?location="${city}"`; // You can send HTTPS requests to external services const weatherResponse = await context.http.get({ url: url.toString(), headers: { Accept: ["application/json"], }, }); const { current, forecasts } = JSON.parse(weatherResponse.body.text()); return [ `Right now ${uppercase(city)} is ${current.temperature}°F and ${current.weather}.`, `Here's the forecast for the next 7 days:`, forecasts .map((f) => `${f.day}: ${f.temperature}°F and ${f.weather}`) .join("\n "), ].join("\n"); };
Right now NEW YORK CITY is 72°F and sunny. Here's the forecast for the next 7 days: Tuesday: 71°F and sunny Wednesday: 72°F and sunny Thursday: 73°F and partly cloudy Friday: 71°F and rainy Saturday: 77°F and sunny Sunday: 76°F and sunny Monday: 74°F and sunny
As funções serializam automaticamente os valores retornados para JSON estendido. Isto é útil para preservar informações de tipo, mas pode não ser o que seu aplicativo espera.
Por exemplo, os valores no objeto retornado da seguinte função são convertidos em valores EJSON estruturados:
exports = function() { return { pi: 3.14159, today: new Date(), } }
{ "pi": { "$numberDouble": "3.14159" }, "today": { "$date": { "$numberLong": "1652297239913" } } }
Para retornar um valor como JSON padrão, chame JSON.stringify()
no valor e, em seguida, retorne o resultado em string:
exports = function() { return JSON.stringify({ pi: 3.14159, today: new Date(), }) }
"{\"pi\":3.14159,\"today\":\"2022-05-11T19:27:32.207Z\"}"
Funções do usuário e do sistema
Uma função pode ser executada em dois contextos, dependendo de como eles são configurados e chamados:
Uma função de usuário é executada no contexto de um usuário específico do seu aplicativo. Normalmente, esse é o usuário conectado que chamou a função. As funções do usuário estão sujeitas às regras e à validação do esquema.
Uma função do sistema é executada como o usuário do sistema em vez de um usuário específico do aplicativo. As funções do sistema têm acesso total às APIs CRUD e de aggregation do MongoDB e ignoram todas as regras e a validação de esquema.
Observação
Referências context.user dinâmicas
As referências a context.user sempre são resolvidas para o usuário autenticado que chamou uma função, se houver um, mesmo que a função seja executada como uma função do sistema. Para determinar se uma função está sendo executada como uma função do sistema, chame context.runningAsSystem()
.
Se uma função for executada sem ser chamada por um usuário autenticado, como em um trigger ou webhook, as referências dinâmicas serão resolvidas para o usuário do sistema que não tem id
ou outros dados associados.
Definir uma função
Você pode criar e gerenciar funções em seu aplicativo a partir da UI do App Services ou importando a configuração da função e o código fonte com App Services CLI ou sistema GitHub.
Chamar uma função
Você pode chamar uma função de outras funções, de um aplicativo cliente conectado ou com o App Services CLI.
Os exemplos nesta seção demonstram a chamada de uma função simples denominada sum
que recebe dois argumentos, os adiciona e retorna o resultado:
// sum: adds two numbers exports = function sum(a, b) { return a + b; };
Chamar de uma função
Você pode chamar uma função de outra função por meio da interface context.functions , que está disponível como uma variável global em qualquer função. Isso inclui Atlas Triggers, HTTPS endpoints e resolvedores personalizados do GraphQL (descontinuado, saiba mais). A função chamada é executada no mesmo contexto da função que a chamou.
// difference: subtracts b from a using the sum function exports = function difference(a, b) { return context.functions.execute("sum", a, -1 * b); };
Chamada do App Services CLI
Você pode chamar uma função por meio da App Services CLI com o comando execução de função. O comando retorna o resultado da função como EJSON, bem como quaisquer mensagens de registro ou de erro.
appservices function run \ --function=sum \ --args=1 --args=2
Por padrão, as funções são executadas no contexto do sistema. Para chamar uma função no contexto de um usuário específico, inclua seu ID de usuário no argumento --user
.
appservices function run \ --function=sum \ --args=1 --args=2 \ --user=61a50d82532cbd0de95c7c89
Chamada de expressões de regras
Você pode chamar uma função de uma expressão de regra usando o operador %function
. O operador avalia o valor de retorno da função. Se a função gerar um erro, a expressão será avaliada como false
.
{ "numGamesPlayed": { "%function": { "name": "sum", "arguments": [ "%%root.numWins", "%%root.numLosses" ] } } }
Chamada de Realm SDK
Importante
Certifique-se de limpar os dados do cliente para se proteger contra a injeção de código ao usar funções.
Você pode chamar uma função de aplicativos clientes que estão conectados com um Realm SDK ou através do protocolo de fio. Para exemplos de código que demonstram como chamar uma função de um aplicativo cliente, consulte a documentação para os Realm SDKs:
Restrições
As funções são limitadas a 300 segundos de tempo de execução por solicitação, após o qual uma função atingirá o tempo limite e falhará.
As funções podem usar até 350MB de memória a qualquer momento.
As funções estão limitadas a 1000 operações assíncronas.
As funções suportam as funcionalidades ES6+ mais comumente usadas e módulos integrados do Node.js. No entanto, algumas funcionalidades incomuns ou inadequadas para cargas de trabalho sem servidor não são suportadas. Para obter mais informações, consulte Suporte a JavaScript.
Uma função pode abrir um máximo de 25 soquetes usando a rede módulo integrado.
As solicitações recebidas são limitadas a um tamanho máximo de 18 MB. Esse limite se aplica ao tamanho total de todos os argumentos passados para a função, bem como qualquer cabeçalho de solicitação ou carga útil se a função for chamada por meio de um ponto de conexão HTTPS.