API TypeScript sem servidor: armazenar dados no MongoDB com o Azure Functions
Crie uma API de Função do Azure para armazenar dados com a API 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.
Observação
Este artigo usa o modelo de programação do Azure Functions Node.js v4 atualmente em visualização.
Preparar seu ambiente de desenvolvimento
Instale o software a seguir:
- Crie uma assinatura do Azure gratuita
- Nó de instalação .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 Azure Explorer 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 os prompts.
Depois de entrar, verifique se o endereço de email da sua conta do Azure aparece na barra de status e as assinaturas aparecem no gerenciador 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 criar recursos nesse grupo, no final do tutorial, você pode excluir o grupo de recursos sem precisar excluir cada recurso individualmente.
Crie uma nova pasta em seu sistema local para usar como raiz do projeto de funções do Azure.
Abra esta pasta no Visual Studio Code.
No Visual Studio Code, abra o Azure Explorer selecionando o ícone do Azure na barra lateral primária ou use o atalho de teclado (Shift + Alt + A).
Encontre sua assinatura em Recursos e selecione o ícone e, em seguida, selecione Criar Grupo de Recursos.+
Use a seguinte tabela para concluir os prompts:
Prompt Valor Insira o nome do novo grupo de recursos. azure-tutorial
Selecione uma localização para novos recursos. Selecione uma região geográfica próxima de você.
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).
Pesquise e selecione Azure Functions: Create New Project .
Use a seguinte tabela para concluir a criação do projeto de Função do Azure local:
Prompt Valor Observações Selecione a pasta que conterá seu projeto de função Selecione a pasta atual (padrão). Selecionar um idioma TypeScript Selecione um modelo de programação TypeScript Modelo V4 (versão prévia) Selecione um modelo para a primeira função do projeto Gatilho HTTP A API é chamada com uma solicitação HTTP. Forneça um nome de função blogposts
A rota da API é /api/blogposts
Quando o Visual Studio Code cria do projeto, exiba
./src/functions/blogposts.ts
seu código de 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 é padrão clichê no novo modelo de programação v4. Ele não pretende 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 do Nó do Azure Functions.js v4 para esse código 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, poderá voltar a usar amethods
propriedade.deleteRequest()
get()
patch()
post()
put()
- O nome da função de
4. Inicie o emulador de armazenamento local do Azurite
O desenvolvimento de funções no 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 do 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 arquivo .gitignore
.
5. Execute a função sem servidor local
Execute o projeto do Azure Functions localmente para testá-lo antes de implantar 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 Azure Explorer 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 navegador, cole a 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 de função e recursos relacionados em sua assinatura do Azure.
No Visual Studio Code, abra a paleta de comandos (Ctrl + Shift + P).
Pesquise e selecione Azure Functions: Create Function App in Azure (Advanced) .
Forneça as seguintes informações nos prompts:
Prompt Seleção Insira um nome exclusivo globalmente para o aplicativo de funções Digite um nome válido em um caminho de URL, como first-function
. Postpend 3 caracteres para tornar a URL globalmente única. O nome que você digitar é validado para ter certeza de que ele é exclusivo no Azure Functions.Selecionar uma pilha de runtime Escolha Node.js 18 LTS ou uma versão mais recente. Selecione um SO Escolha Linux. Selecione 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 o 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ções existente sempre substitui o conteúdo do aplicativo no Azure.
- Escolha o ícone do Azure na barra de atividades e, na área Recursos, clique com o botão direito do mouse no recurso do aplicativo de função e selecione o aplicativo Implantar para 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 exibir os resultados. Se você perder a notificação, selecione o ícone de sino no canto inferior direito para vê-lo novamente.
8. Adicionar configuração de aplicativo ao aplicativo na nuvem
Escolha o ícone do Azure na barra de atividades e, 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).
Configuração Valor AzureWebJobsFeatureFlags EnableWorkerIndexing
9. Execute a função remota sem servidor
No Visual Studio Code, abra o Azure Explorer 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 de aplicativo Função do Azure. Clique com o botão direito do mouse no nome da função e selecione Copiar URL da função.
Cole a 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 de 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 Azure Explorer 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 recurso do Azure Cosmos DB.
Prompt Valor Observações Selecionar um servidor de banco de dados do Azure Azure Cosmos DB para a API do 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 se torna parte da 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 uma localização 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. Adicionar código mongoose 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 arquivo
./src/functions/blogposts
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 Azure Explorer 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 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 no Azure porque está incluído no
./.funcignore
arquivo. - Não é verificado no controle do código-fonte porque está incluído no
./.gitignore
arquivo.
- Não é implantado no Azure porque está incluído no
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 Azure Explorer 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 de Aplicativo e selecione Adicionar Nova Configuração.
- Insira o nome
MONGODB_URI
da configuração do aplicativo e selecione Enter. - Cole o valor copiado e pressione enter.
15. Adicionar 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 esse 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 Azure Explorer 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 postagens de blog para exibir os documentos.
Selecione um dos itens listados para exibir os dados na instância do Azure Cosmos DB.
17. Reimplantar o aplicativo de função para incluir o código do banco de dados
- No Visual Studio Code, abra o Azure Explorer 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 Função do Azure e selecione Implantar no Aplicativo de Função.
- No pop-up perguntando se você tem certeza de que deseja implantar, selecione Implantar.
- Aguarde até a implantação ser concluída para continuar.
18. Usar a função do Azure baseada 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 os logs de Função do Azure
Para pesquisar os logs, use o portal do Azure.
No Visual Studio Code, selecione o Azure Explorer e, em seguida, 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 a Função do Azure.
Em Configurações, selecione Application Insights e, em seguida, selecione Exibir dados do Application Insights.
Esse link direciona você ao recurso de métricas separado criado no momento da criação da sua Função do Azure com o Visual Studio Code.
Na seção Monitoramento , selecione Logs. Se uma janela pop-up de Consultas for exibida, selecione o X no canto superior direito para fechar.
No painel Nova Consulta 1, na guia Tabelas, clique duas vezes na tabela Rastreamentos.
Isso insere a consulta Kusto,
traces
na janela de consulta.Edite a consulta para pesquisar 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.
Não é preciso executar ações adicionais para obter estas informações de log:
- O código usou a
context.log
função fornecida pela estrutura Function.context
Usando , em vez de , seu log pode ser filtradoconsole
para a função individual específica. Isso é útil se o aplicativo Function tiver muitas funções. - O aplicativo de funções 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 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 Azure Explorer selecionando o ícone do Azure na barra lateral primária ou use o atalho de teclado (Shift + Alt + A).
- Pesquise 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óximas etapas
Comentários
https://aka.ms/ContentUserFeedback.
Em breve: Ao longo de 2024, eliminaremos os problemas do GitHub como o mecanismo de comentários para conteúdo e o substituiremos por um novo sistema de comentários. Para obter mais informações, consulteEnviar e exibir comentários de