API Serverless TypeScript: armazene dados no MongoDB com o Azure Functions
Crie uma API do Azure Function para armazenar dados com a API do Mongoose no Azure Cosmos DB e, em seguida, implante o aplicativo Function na nuvem do Azure para hospedagem com um ponto de extremidade HTTP público.
Nota
Este artigo usa o modelo de programação v4 do Azure Functions Node.js atualmente em visualização.
Preparar o ambiente de desenvolvimento
Instale o seguinte software:
- Criar uma subscrição gratuita do Azure
- Instale o nó.js LTS v18+
- TypeScript v4+
- Azurite instalado globalmente para armazenamento de desenvolvimento local
- Azure Functions Runtime v4.16+
- Azure Functions Core Tools v4.0.5095+ (se executado localmente) instalado globalmente para desenvolvimento local
- Instale o Visual Studio Code e use as seguintes extensões:
1. Entre no Azure no Visual Studio Code
Se você já usa as extensões de serviço do Azure, já deve estar conectado e pode ignorar esta etapa.
Depois de instalar uma extensão de serviço do Azure no Visual Studio Code, você precisa entrar em sua conta do Azure.
No Visual Studio Code, abra o explorador do Azure selecionando o ícone do Azure na barra lateral primária ou use o atalho de teclado (Shift + Alt + A).
Na seção Recursos, selecione Entrar no Azure e siga as instruções.
Depois de iniciar sessão, verifique se o endereço de e-mail da sua conta do Azure aparece na Barra de Estado e se a(s) sua(s) subscrição(ões) aparece(m) no explorador do Azure :
2. Criar um grupo de recursos do Azure
Um grupo de recursos é uma coleção de recursos baseada em região. Ao criar um grupo de recursos e, em seguida, criar recursos nesse grupo, no final do tutorial, você pode excluir o grupo de recursos sem ter que excluir cada recurso individualmente.
Crie uma nova pasta em seu sistema local para usar como a raiz do projeto de funções do Azure.
Abra esta pasta no Visual Studio Code.
No Visual Studio Code, abra o explorador do Azure selecionando o ícone do Azure na barra lateral primária ou use o atalho de teclado (Shift + Alt + A).
Encontre a sua subscrição em Recursos e selecione o ícone e, em seguida, selecione Criar Grupo de Recursos.+
Use a tabela a seguir para concluir os prompts:
Prompt valor Insira o nome do novo grupo de recursos. azure-tutorial
Selecione um local para seus novos recursos. Selecione uma região geográfica perto de si.
3. Crie o aplicativo Functions local
Crie um aplicativo local do Azure Functions (sem servidor) que contenha uma função de gatilho HTTP.
No Visual Studio Code, abra a paleta de comandos (Ctrl + Shift + P).
Procure e selecione Azure Functions: Criar Novo Projeto .
Use a tabela a seguir para concluir a criação do projeto local do Azure Function:
Prompt valor Notas Selecione a pasta que conterá seu projeto de função Selecione a pasta atual (padrão). Escolha um idioma TypeScript Selecione um modelo de programação TypeScript Modelo V4 (Pré-visualização) Selecione um modelo para a primeira função do seu projeto Acionador HTTP A API é invocada com uma solicitação HTTP. Fornecer um nome de função blogposts
A rota da API é /api/blogposts
Quando o Visual Studio Code cria o projeto, exiba
./src/functions/blogposts.ts
o código da API no arquivo.import { app, HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions"; export async function blogposts(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> { context.log(`Http function processed request for url "${request.url}"`); const name = request.query.get('name') || await request.text() || 'world'; return { body: `Hello, ${name}!` }; }; app.http('blogposts', { methods: ['GET', 'POST'], authLevel: 'anonymous', handler: blogposts });
Este código é clichê padrão no novo modelo de programação v4. Não se destina a indicar a única maneira de escrever uma camada de API com POST e GET.
Substitua o código anterior pelo código a seguir para permitir que apenas solicitações GET retornem todas as postagens de blog.
import { app, HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions"; // curl --location 'http://localhost:7071/api/blogposts' --verbose export async function getBlogPosts(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> { context.log(`Http function getBlogPosts processed request for url "${request.url}"`); // Empty array for now ... will fix later const blogposts = []; return { status: 200, jsonBody: { blogposts } }; }; app.get('getBlogPosts', { route: "blogposts", authLevel: 'anonymous', handler: getBlogPosts });
Há várias alterações no modelo de programação v4 do Azure Functions Node.js v4 que você deve observar:
- O nome da função de
getBlobPosts
, indicando que é uma solicitação GET, ajudará você a isolar a função nos logs. - A
route
propriedade é definida comoblogposts
, que faz parte da rota de API padrão fornecida,/api/blogposts
. - A
methods
propriedade foi removida e é desnecessária porque oapp
uso do objeto indicaget
que esta é uma solicitação GET. As funções do método estão listadas abaixo. Se você tiver um método diferente, você pode voltar a usar amethods
propriedade.deleteRequest()
get()
patch()
post()
put()
- O nome da função de
4. Inicie o emulador de armazenamento local Azurite
O desenvolvimento de funções em seu computador local requer um emulador de armazenamento (gratuito) ou uma conta de armazenamento do Azure (paga).
Em um terminal separado, inicie o emulador de armazenamento local Azurite.
azurite --silent --location ./azurite --debug ./azurite/debug.log
Isso é necessário para executar o Azure Functions localmente usando um emulador de Armazenamento do Azure local. O emulador de armazenamento local é especificado no local.settings.json
arquivo com a propriedade AzureWebJobsStorage com um valor de UseDevelopmentStorage=true
.
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "node",
"AzureWebJobsFeatureFlags": "EnableWorkerIndexing"
}
}
A azurite
subpasta já foi adicionada ao seu .gitignore
ficheiro.
5. Execute a função serverless local
Execute o projeto do Azure Functions localmente para testá-lo antes de implantá-lo no Azure.
No Visual Studio Code, defina um ponto de interrupção na
return
instrução, no final da função getBlogPosts .No Visual Studio Code, pressione F5 para iniciar o depurador e anexá-lo ao host do Azure Functions.
Você também pode usar o comando de menu Depurar Iniciar Depuração>.
A saída aparece no painel Terminal .
No Visual Studio Code, abra o explorador do Azure selecionando o ícone do Azure na barra lateral primária ou use o atalho de teclado (Shift + Alt + A).
Na seção Espaço de trabalho, localize e expanda o Projeto Local -Functions ->>getBlogPosts.
Clique com o botão direito do mouse no nome da função, getBlogPosts, e selecione Copiar URL da função.
No seu navegador, cole o URL e selecione Enter ou use o seguinte comando cURL no terminal:
curl http://localhost:7071/api/blogposts --verbose
A resposta de uma matriz vazia de postagens de blog é retornada como:
* Trying 127.0.0.1:7071... * Connected to localhost (127.0.0.1) port 7071 (#0) > GET /api/blogposts HTTP/1.1 > Host: localhost:7071 > User-Agent: curl/7.88.1 > Accept: */* > < HTTP/1.1 200 OK < Content-Type: application/json < Date: Mon, 08 May 2023 17:35:24 GMT < Server: Kestrel < Transfer-Encoding: chunked < {"blogposts":[]}* Connection #0 to host localhost left intact
No VS Code, pare o depurador, Shift + F5.
6. Criar o aplicativo Azure Function no Visual Studio Code
Nesta seção, você cria um recurso de nuvem de aplicativo funcional e recursos relacionados em sua assinatura do Azure.
No Visual Studio Code, abra a paleta de comandos (Ctrl + Shift + P).
Procure e selecione Azure Functions: Create Function App in Azure (Advanced) .
Forneça as seguintes informações nos pedidos:
Prompt Seleção Insira um nome globalmente exclusivo para o aplicativo de função Digite um nome válido em um caminho de URL, como first-function
. Postpend 3 caracteres para tornar o URL globalmente único. O nome digitado é validado para garantir que seja exclusivo no Azure Functions.Selecione uma pilha de tempo de execução Escolha Node.js 18 LTS ou uma versão mais recente. Selecione um SO Escolha Linux. Selecionar um grupo de recursos para novos recursos Crie um novo grupo de recursos chamado azure-tutorial-first-function. Esse grupo de recursos eventualmente terá vários recursos: Função do Azure, Armazenamento do Azure e a API do Cosmos DB para MongoDB. Selecione um plano de hospedagem Escolha Consumo. Selecione uma conta de armazenamento Selecione Criar uma nova conta de armazenamento e aceite o nome padrão. Selecione um recurso do Application Insights para seu aplicativo. Selecione Criar novo recurso do Application Insights e aceite o nome padrão. Aguarde até que a notificação confirme que o aplicativo foi criado.
7. Implantar o aplicativo Azure Function no Azure no Visual Studio Code
Importante
A implantação em um aplicativo de função existente sempre substitui o conteúdo desse aplicativo no Azure.
- Escolha o ícone do Azure na barra de atividades e, em seguida, na área Recursos, clique com o botão direito do mouse no recurso do aplicativo de função e selecione Implantar no aplicativo de função.
- Se você for perguntado se tem certeza de que deseja implantar, selecione Implantar.
- Após a conclusão da implantação, uma notificação é exibida com várias opções. Selecione Exibir saída para visualizar os resultados. Se você perder a notificação, selecione o ícone de sino no canto inferior direito para vê-lo novamente.
8. Adicionar a configuração do aplicativo ao aplicativo na nuvem
Escolha o ícone do Azure na barra de atividades e, em seguida, na área Recursos, expanda o recurso do aplicativo de função e clique com o botão direito do mouse em Configurações do aplicativo.
Selecione Adicionar nova configuração e adicione a seguinte configuração para habilitar o modelo de programação Node.js v4 (Preview).
Definição valor AzureWebJobsFeatureFlags EnableWorkerIndexing
9. Execute a função remota sem servidor
No Visual Studio Code, abra o explorador do Azure selecionando o ícone do Azure na barra lateral primária ou use o atalho de teclado (Shift + Alt + A).
Na seção Recursos, expanda seu recurso do aplicativo Azure Function. Clique com o botão direito do mouse no nome da função e selecione Copiar URL da função.
Cole o URL em um navegador. A mesma matriz vazia é retornada como quando você executou a função localmente.
{"blogposts":[]}
10. Adicionar o Azure Cosmos DB para integração da API do MongoDB
O Azure Cosmos DB fornece uma API do MongoDB para fornecer um ponto de integração familiar.
No Visual Studio Code, abra o explorador do Azure selecionando o ícone do Azure na barra lateral primária ou use o atalho de teclado (Shift + Alt + A).
Na seção Recursos, selecione Criar +Servidor de Banco de Dados. Use a tabela a seguir para concluir os prompts para criar um novo recurso do Azure Cosmos DB.
Prompt valor Notas Selecione um Servidor de Banco de Dados do Azure API do Azure Cosmos DB para MongoDB Forneça um nome de conta do Azure Cosmos DB. cosmosdb-mongodb-database
Poste três caracteres para criar um nome exclusivo. O nome torna-se parte do URL da API. Selecione um modelo de capacidade. Sem servidor Selecione um grupo de recursos para novos recursos. azure-tutorial-first-function Selecione o grupo de recursos criado em uma seção anterior. Selecione um local para novos recursos. Selecione a região recomendada.
11. Instale a dependência do mangusto
Em um terminal do Visual Studio Code, Ctrl + Shift + ` e, em seguida, instale o pacote npm:
npm install mongoose
12. Adicione código de mangusto para postagens de blog
No Visual Studio Code, crie um subdiretório chamado lib at
./src/
, crie um arquivo chamado./database.ts
e copie o código a seguir para ele.import { Schema, Document, createConnection, ConnectOptions, model, set } from 'mongoose'; const connectionString = process.env.MONGODB_URI; console.log('connectionString', connectionString); const connection = createConnection(connectionString, { useNewUrlParser: true, useUnifiedTopology: true, autoIndex: true } as ConnectOptions); export interface IBlogPost { author: string title: string body: string } export interface IBlogPostDocument extends IBlogPost, Document { id: string created: Date } const BlogPostSchema = new Schema({ id: Schema.Types.ObjectId, author: String, title: String, body: String, created: { type: Date, default: Date.now } }); BlogPostSchema.set('toJSON', { transform: function (doc, ret, options) { ret.id = ret._id; delete ret._id; delete ret.__v; } }); export const BlogPost = model<IBlogPostDocument>('BlogPost', BlogPostSchema); connection.model('BlogPost', BlogPostSchema); export default connection;
No Visual Studio Code, abra o
./src/functions/blogposts
arquivo e substitua o código do arquivo inteiro pelo seguinte:import { app, HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions"; import connection from '../lib/database'; // curl --location 'http://localhost:7071/api/blogposts' --verbose export async function getBlogPosts(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> { context.log(`Http function getBlogPosts processed request for url "${request.url}"`); const blogposts = await connection.model('BlogPost').find({}); return { status: 200, jsonBody: { blogposts } }; }; app.get('getBlogPosts', { route: "blogposts", authLevel: 'anonymous', handler: getBlogPosts });
13. Adicionar cadeia de conexão ao aplicativo local
No explorador do Azure do Visual Studio Code, selecione a seção Azure Cosmos DB e expanda para clicar com o botão direito do mouse em selecionar seu novo recurso.
Selecione Copiar cadeia de conexão.
No Visual Studio Code, use o Explorador de arquivos para abrir
./local.settings.json
o .Adicione uma nova propriedade chamada
MONGODB_URI
e cole o valor da sua cadeia de conexão.{ "IsEncrypted": false, "Values": { "AzureWebJobsStorage": "", "FUNCTIONS_WORKER_RUNTIME": "node", "AzureWebJobsFeatureFlags": "EnableWorkerIndexing", "MONGODB_URI": "mongodb://...." } }
Os segredos no
./local.settings.json
arquivo:- Não é implantado
./.funcignore
no Azure porque está incluído no arquivo. - Não está verificado no controle do código-fonte porque está incluído no
./.gitignore
arquivo.
- Não é implantado
Execute o aplicativo localmente e teste a API com a mesma url na seção anterior.
14. Adicionar cadeia de conexão ao aplicativo remoto
- No Visual Studio Code, abra o explorador do Azure selecionando o ícone do Azure na barra lateral primária ou use o atalho de teclado (Shift + Alt + A).
- Na seção Recursos, localize sua instância do Azure Cosmos DB. Clique com o botão direito do mouse no recurso e selecione Copiar cadeia de conexão.
- Na mesma seção Recursos , localize seu aplicativo de função e expanda o nó.
- Clique com o botão direito do mouse em Configurações do aplicativo e selecione Adicionar nova configuração.
- Introduza o nome
MONGODB_URI
da definição da aplicação e selecione Enter. - Cole o valor copiado e pressione enter.
15. Adicione APIs para criar, atualizar e excluir postagens de blog
No Visual Studio Code, use a paleta de comandos para localizar e selecionar Azure Functions: Create function.
Selecione o gatilho HTTP e nomeie-o
blogpost
(singular).Copie o código a seguir para o arquivo.
import { app, HttpRequest, HttpResponseInit, InvocationContext } from "@azure/functions"; import connection, { IBlogPost, IBlogPostDocument } from '../lib/database'; // curl -X POST --location 'http://localhost:7071/api/blogpost' --header 'Content-Type: application/json' --data '{"author":"john","title":"my first post", "body":"learn serverless node.js"}' --verbose export async function addBlogPost(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> { context.log(`Http function addBlogPost processed request for url "${request.url}"`); const body = await request.json() as IBlogPost; const blogPostResult = await connection.model('BlogPost').create({ author: body?.author, title: body?.title, body: body?.body }); return { status: 200, jsonBody: { blogPostResult } }; }; // curl -X PUT --location 'http://localhost:7071/api/blogpost/64568e727f7d11e09eab473c' --header 'Content-Type: application/json' --data '{"author":"john jones","title":"my first serverless post", "body":"Learn serverless Node.js with Azure Functions"}' --verbose export async function updateBlogPost(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> { context.log(`Http function updateBlogPost processed request for url "${request.url}"`); const body = await request.json() as IBlogPost; const id = request.params.id; const blogPostResult = await connection.model('BlogPost').updateOne({ _id: id }, { author: body?.author, title: body?.title, body: body?.body }); if(blogPostResult.matchedCount === 0) { return { status: 404, jsonBody: { message: 'Blog post not found' } }; } return { status: 200, jsonBody: { blogPostResult } }; }; // curl --location 'http://localhost:7071/api/blogpost/6456597918547e37d515bda3' --verbose export async function getBlogPost(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> { context.log(`Http function getBlogPosts processed request for url "${request.url}"`); console.log('request.params.id', request.params.id) const id = request.params.id; const blogPost = await connection.model('BlogPost').findOne({ _id: id }); if(!blogPost) { return { status: 404, jsonBody: { message: 'Blog post not found' } }; } return { status: 200, jsonBody: { blogPost } }; }; // curl --location 'http://localhost:7071/api/blogpost/6456597918547e37d515bda3' --request DELETE --header 'Content-Type: application/json' --verbose export async function deleteBlogPost(request: HttpRequest, context: InvocationContext): Promise<HttpResponseInit> { context.log(`Http function deleteBlogPost processed request for url "${request.url}"`); const id = request.params.id; const blogPostResult = await connection.model('BlogPost').deleteOne({ _id: id }); if(blogPostResult.deletedCount === 0) { return { status: 404, jsonBody: { message: 'Blog post not found' } }; } return { status: 200, jsonBody: { blogPostResult } }; }; app.get('getBlogPost', { route: "blogpost/{id}", authLevel: 'anonymous', handler: getBlogPost }); app.post('postBlogPost', { route: "blogpost", authLevel: 'anonymous', handler: addBlogPost }); app.put('putBlogPost', { route: "blogpost/{id}", authLevel: 'anonymous', handler: updateBlogPost }); app.deleteRequest('deleteBlogPost', { route: "blogpost/{id}", authLevel: 'anonymous', handler: deleteBlogPost });
Inicie a função local com o depurador novamente. As seguintes APIs estão disponíveis:
deleteBlogPost: [DELETE] http://localhost:7071/api/blogpost/{id} getBlogPost: [GET] http://localhost:7071/api/blogpost/{id} getBlogPosts: [GET] http://localhost:7071/api/blogposts postBlogPost: [POST] http://localhost:7071/api/blogpost putBlogPost: [PUT] http://localhost:7071/api/blogpost/{id}
Use a
blogpost
API (singular) de um comando cURL para adicionar algumas postagens de blog.curl -X POST --location 'http://localhost:7071/api/blogpost' --header 'Content-Type: application/json' --data '{"author":"john","title":"my first post", "body":"learn serverless node.js"}' --verbose
Use a
blogposts
API (plural) de um comando cURL para obter as postagens do blog.curl http://localhost:7071/api/blogposts --verbose
16. Exibir todos os dados com a extensão de código do Visual Studio para o Azure Cosmos DB
No Visual Studio Code, abra o explorador do Azure selecionando o ícone do Azure na barra lateral primária ou use o atalho de teclado (Shift + Alt + A).
Na seção Recursos, clique com o botão direito do mouse no banco de dados do Azure Cosmos DB e selecione Atualizar.
Expanda o banco de dados de teste e os nós da coleção de blogposts para exibir os documentos.
Selecione um dos itens listados para exibir os dados na instância do Azure Cosmos DB.
17. Reimplante o aplicativo de função para incluir o código do banco de dados
- No Visual Studio Code, abra o explorador do Azure selecionando o ícone do Azure na barra lateral primária ou use o atalho de teclado (Shift + Alt + A).
- Na seção Recursos, clique com o botão direito do mouse em seu aplicativo Azure Function e selecione Implantar no Aplicativo de Função.
- No pop-up perguntando se você tem certeza de que deseja implantar, selecione Implantar.
- Aguarde até que a implantação seja concluída antes de continuar.
18. Usar o Azure Function baseado em nuvem
- Ainda no Azure Explorer, na área Funções, seleciona e expande sua função e, em seguida, o nó Funções , que lista as APIs
- Clique com o botão direito do mouse em uma das APIs e selecione Copiar URL da função.
- Edite os comandos cURL anteriores para usar a URL remota em vez da URL local. Execute os comandos para testar a API remota.
19. Consultar seus logs do Azure Function
Para pesquisar os logs, use o portal do Azure.
No Visual Studio Code, selecione o Azure Explorer e, em Funções, clique com o botão direito do mouse em seu aplicativo de função e selecione Abrir no Portal.
Isso abre o portal do Azure para sua Função do Azure.
Em Configurações, selecione Application Insights e, em seguida, selecione Exibir dados do Application Insights.
Este link leva você ao seu recurso de métricas separado criado para você quando você criou sua Função do Azure com o Visual Studio Code.
Na seção Monitoramento, selecione Logs. Se aparecer uma janela pop-up Consultas , selecione o X no canto superior direito do pop-up para fechá-la.
No painel Nova Consulta 1, na guia Tabelas, clique duas vezes na tabela de rastreamentos.
Isso insere a consulta Kusto,
traces
na janela de consulta.Edite a consulta para procurar os logs personalizados:
traces | where message startswith "***"
Selecione Executar.
Se o log não exibir nenhum resultado, pode ser porque há um atraso de alguns minutos entre a solicitação HTTP para a Função do Azure e a disponibilidade do log no Kusto. Aguarde alguns minutos e execute a consulta novamente.
Você não precisou fazer nada a mais para obter essas informações de registro:
- O código usou a
context.log
função fornecida pela estrutura Function.context
Usando , em vez de , seu registro pode ser filtradoconsole
para a função individual específica. Isso é útil se o seu aplicativo Function tiver muitas funções. - O aplicativo Function adicionou o Application Insights para você.
- A ferramenta Kusto Query está incluída no portal do Azure.
- Você pode selecionar
traces
em vez de ter que aprender a escrever uma consulta Kusto para obter até mesmo as informações mínimas de seus logs.
- O código usou a
20. Limpar os recursos
Como você usou um único grupo de recursos, pode excluir todos os recursos excluindo o grupo de recursos.
- No Visual Studio Code, abra o explorador do Azure selecionando o ícone do Azure na barra lateral primária ou use o atalho de teclado (Shift + Alt + A).
- Procure e selecione Azure: Agrupar por grupo de recursos.
- Clique com o botão direito do mouse em selecionar seu grupo de recursos e selecione Excluir grupo de recursos.
- Insira o nome do grupo de recursos para confirmar a exclusão.
Código fonte disponível
Código fonte completo para este aplicativo Azure Function:
Próximos passos
Comentários
https://aka.ms/ContentUserFeedback.
Brevemente: Ao longo de 2024, vamos descontinuar progressivamente o GitHub Issues como mecanismo de feedback para conteúdos e substituí-lo por um novo sistema de feedback. Para obter mais informações, veja:Submeter e ver comentários