Migración de una aplicación MEAN a Arquitectura Serverless y Azure Functions
Tags: javascript, tutorial, serverless, webdev
Published: 2019-09-12 10:58:00

---
title: Migración de una aplicación MEAN a Arquitectura Serverless y Azure Functions
published: true
description: ¡Durante este artículo usted aprenderá cómo migrar de manera simple, rápida y dinámica una aplicación MEAN a una arquitectura Serverless usando Azure Functions!
tags: #javascript #tutorial #serverless #webdev
series: Migración app MEAN a Azure Functions
---

Este artículo es parte de la colección de contenidos [#ServerlessSeptember](https://dev.to/azure/serverless-september-content-collection-2fhb). Aquí encontrarás todos los artículos publicados durante el mes de septiembre de 2019.

¡Durante este artículo aprenderá cómo migrar de manera simple, rápida y dinámica una aplicación MEAN a una arquitectura Serverless usando Azure Functions!

El proyecto MEAN ya está listo y puedes hacer un git cline o descargarlo **[AQUI](https://github.com/glaucia86/workshop-mean-serverless)**

¡¿Aquí vamos?!

## Comprendendo la estructura del proyecto MEAN

En este proyecto nos centraremos en las dos carpetas: **api** y **front**. Como la imagen de abajo:

[![Screen-Shot-09-11-19-at-12-04-PM.png](https://i.postimg.cc/mk6wmMnv/Screen-Shot-09-11-19-at-12-04-PM.png)](https://postimg.cc/RJKKF34d)

Si ejecuta esta aplicación, notará que estamos persistiendo en MongoDb y estamos usando Back End, que en este caso estamos usando Node.js.

Los datos persistentes consisten en:

**Classe: Funcionario**

+ **idFuncionario:** (number - guid generado por el MongoDb)
+ **nomeFuncionario:** string
+ **cargo:** string
+ **numeroIdentificador:** number

Si desea ejecutar este proyecto localmente, solo siga los pasos en README.md desde el repositorio del proyecto.

Bueno, ahora que tiene el proyecto MEAN en la mano, ¡comencemos a migrar a Azure Functions?

Pero en primer lugar, vamos a entender lo que serían Azure Functions!

## ¿Qué son Azure Functions? ⚡️

**[Azure Functions](https://azure.microsoft.com/es-es/services/functions/?WT.mc_id=servsept_devto-blog-gllemos)** es un servicio de proceso sin servidor que le permite ejecutar código a petición sin necesidad de aprovisionar ni administrar explícitamente la infraestructura. 

Y Azure Functions tiene soporte varias lenguajes de programación, que incluyen:

- **[C#](https://docs.microsoft.com/es-es/azure/azure-functions/functions-reference-csharp?WT.mc_id=servsept_devto-blog-gllemos)**
- **[JavaScript](https://docs.microsoft.com/es-es/azure/azure-functions/functions-reference-node?WT.mc_id=servsept_devto-blog-gllemos)**
- **[F#](https://docs.microsoft.com/es-es/azure/azure-functions/functions-reference-fsharp?WT.mc_id=servsept_devto-blog-gllemos)**
- **[Java](https://docs.microsoft.com/es-es/azure/azure-functions/functions-reference-java?WT.mc_id=servsept_devto-blog-gllemos)**
- **[PowerShell](https://docs.microsoft.com/es-es/azure/azure-functions/functions-reference-powershell?WT.mc_id=servsept_devto-blog-gllemos)**
- **[Python](https://docs.microsoft.com/es-es/azure/azure-functions/functions-reference-python?WT.mc_id=servsept_devto-blog-gllemos)**
- **[TypeScript](https://docs.microsoft.com/es-es/azure/azure-functions/functions-reference-node?WT.mc_id=servsept_devto-blog-gllemos#typescript)**

Ya las lenguajes abajo, ya son compatibles, pero están en su versión preview:

- **Bash**
- **PHP**

Si desea conocer más detalles sobre las lenguajes que tiene soporte a Azure Functions, visite el enlace **[AQUÍ](https://docs.microsoft.com/es-es/azure/azure-functions/supported-languages?WT.mc_id=servsept_devto-blog-gllemos)**

Sin embargo, para este artículo nos centraremos en JavaScript. 😉

## Plantillas importantes en Azure Functions

Antes de comenzar a migrar, es importante mencionar que Azure Functions tiene varias plantillas listas para usar. Entre ellos:

- **[HTTPTrigger](https://docs.microsoft.com/es-es/azure/azure-functions/functions-create-first-azure-function?WT.mc_id=servsept_devto-blog-gllemos)**
- **[TimerTrigger](https://docs.microsoft.com/es-es/azure/azure-functions/functions-create-scheduled-function?WT.mc_id=servsept_devto-blog-gllemos)**
- **[CosmosDBTrigger](https://docs.microsoft.com/es-es/azure/azure-functions/functions-bindings-cosmosdb-v2?WT.mc_id=servsept_devto-blog-gllemos)**
- **[BlobTrigger](https://docs.microsoft.com/es-es/azure/azure-functions/functions-bindings-storage-blob?WT.mc_id=servsept_devto-blog-gllemos)**
- **[QueueTrigger](https://docs.microsoft.com/es-es/azure/azure-functions/functions-bindings-storage-queue?WT.mc_id=servsept_devto-blog-gllemos)**
- **[EventGridTrigger](https://docs.microsoft.com/es-es/azure/event-grid/resize-images-on-storage-blob-upload-event?tabs=dotnet&WT.mc_id=servsept_devto-blog-gllemos)**
- **[EventHubTrigger](https://docs.microsoft.com/es-es/azure/azure-functions/functions-bindings-event-hubs?WT.mc_id=servsept_devto-blog-gllemos)**
- **[ServiceBusQueueTrigger](https://docs.microsoft.com/es-es/azure/azure-functions/functions-bindings-service-bus?WT.mc_id=servsept_devto-blog-gllemos)**
- **[ServiceBusTopicTrigger](https://docs.microsoft.com/es-es/azure/azure-functions/functions-bindings-service-bus?WT.mc_id=servsept_devto-blog-gllemos)**

No entraré en detalles de cada una de las plantillas, de lo contrario este artículo será muy grande. Pero si desea comprender más acerca de cada plantilla y cuál es su mejor uso en una aplicación en particular, le recomiendo leer la documentación **[AQUÍ](https://docs.microsoft.com/es-es/azure/azure-functions/functions-overview?WT.mc_id=servsept_devto-blog-gllemos)**.

Para este post, vamos a hacer uso de **[HTTPTrigger](https://docs.microsoft.com/es-es/azure/azure-functions/functions-create-first-azure-function?WT.mc_id=servsept_devto-blog-gllemos)** ya que esta plantilla activa la ejecución de su código usando una solicitud HTTP. ¡Y eso es justo lo que necesitaremos!

Si es estudiante en cualquier colegio o universidad, puede crear su cuenta de Azure for Students **[Azure for Students](https://azure.microsoft.com/es-es/free/students/?WT.mc_id=servsept_devto-blog-gllemos)**. Essa conta te dará o benefício em possuir crédito de USD 100,00 para usar os serviços de maneira gratuita, sem necessidade de possuir um cartão de crédito. Para ativar essa conta, bastam acessar o link ao lado: **[AQUI](https://azure.microsoft.com/es-es/free/students/?WT.mc_id=servsept_devto-blog-gllemos)** ¡Con esta cuenta puede hacer uso de **1,000,000 solicitudes gratuitas por mes para procesar eventos en Azure Functions!**

[![Screen-Shot-09-11-19-at-12-42-PM.png](https://i.postimg.cc/Jh68m7sR/Screen-Shot-09-11-19-at-12-42-PM.png)](https://postimg.cc/5HCTSV5r)

Bueno, después de esta descripción general de Azure Functions, ¡finalmente podemos comenzar nuestra migración! ¡Vamos adelante!

## Instalación del paquete Azure Functions Core Tools

**[Azure Functions Core Tools](https://docs.microsoft.com/azure/azure-functions/functions-run-local?WT.mc_id=servsept_devto-blog-gllemos)** le permite desarrollar y probar funciones en el equipo local desde el prompt command del sistema o usando el terminal. 

Estos son los programas y el paquete que necesitamos para continuar en nuestro tutorial:

* **[Node.js - LTS](https://nodejs.org/en/)**
* **[Azure Functions Core Tools](https://www.npmjs.com/package/azure-functions-core-tools)**
* **[Mongo Compass](https://www.mongodb.com/products/compass)**

Una vez que tenga Node.js instalado en su máquina, simplemente escriba el siguiente comando:

* **Windows**

```bash
npm install -g azure-functions-core-tools
```

* **MacOs**

```bash
brew tap azure/functions
brew install azure-functions-core-tools
```

* **Linux (Ubuntu/Debian) com APT**

```bash
curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
sudo mv microsoft.gpg /etc/apt/trusted.gpg.d/microsoft.gpg
```

Para obtener más información para instalar correctamente Azure Functions Core Tools, visite el enlace **[AQUÍ](https://docs.microsoft.com/azure/azure-functions/functions-run-local?WT.mc_id=servsept_devto-blog-gllemos)**

¿Y cómo sé si Azure Functions Core Tools están instaladas correctamente? Simplemente escriba el siguiente comando en el terminal:

```bash
> func
```

Si sucede de acuerdo con el siguiente gif, es porque el paquete se instaló correctamente.

[![gif-serverless-07.gif](https://s3.gifyu.com/images/gif-serverless-07.gif)](https://gifyu.com/image/hYvM)

Genial! Ahora podemos crear nuestras funciones. Para hacer esto, cree una carpeta local en su máquina y ¡comencemos!

## Creando una nueva aplicación en Azure Functions

Ahora que tenemos el paquete instalado, creemos una nueva aplicación. Para hacer esto, solo siga los pasos como el gif:

[![gif-serverless-08.gif](https://s3.gifyu.com/images/gif-serverless-08.gif)](https://gifyu.com/image/hYqP)

Tenga en cuenta que cuando abrimos Visual Studio Code, debemos hacer clic en el botón `YES` que aparece en la esquina inferior derecha para habilitar algunos archivos importantes en el proyecto.

## Creando una conexión en MongoDb

Bueno, ahora hagamos algunos cambios necesarios en nuestro proyecto recién creado. Para esto, instalaremos localmente el **[mongodb](https://www.npmjs.com/package/mongodb)** en nuestro proyecto. Escriba el siguiente comando:

```bash
> npm install mongodb
```

Al instalar mongoDb en el proyecto, tenga en cuenta que ha habido cambios en el archivo `package.json`. Al final, el archivo debe ser el siguiente:

* **archivo: package.json**

```json
{
  "name": "crud-serverless-mongodb",
  "version": "1.0.0",
  "description": "Projeto azure functions com persistencia com o mongoDb",
  "scripts": {
    "test": "echo \"No tests yet...\""
  },
  "author": "",
  "dependencies": {
    "mongodb": "^3.3.2"
  }
}
```

Ahora creemos una carpeta llamada: `shared` y dentro crearemos el archivo:` mongo.js`. La estructura del proyecto ahora se verá de la siguiente manera:

[![Screen-Shot-09-11-19-at-02-05-PM.png](https://i.postimg.cc/SxnBMnf5/Screen-Shot-09-11-19-at-02-05-PM.png)](https://postimg.cc/CRVryLtH)

Ahora cambiemos el archivo `mongo.js`. Para hacer esto, incluya el siguiente código:

* **archivo: shared/mongo.js**

```javascript
/**
 * Arquivo: mongo.js
 * Data: 10/11/2019
 * Descrição: arquivo responsável por tratar a conexão da Base de Dados localmente
 * Author: Glaucia Lemos
 */

const { MongoClient } = require("mongodb");

const config = {
  url: "mongodb://localhost:27017/crud-serverless-mongodb",
  dbName: "crud-serverless-mongodb"
};

async function createConnection() {
  const connection = await MongoClient.connect(config.url, {
    useNewUrlParser: true
  });
  const db = connection.db(config.dbName);
  return {
    connection,
    db
  };
}

module.exports = createConnection;
```

¡Aquí estamos creando nuestra conexión local con MongoDb! ¡Muy parecido a lo que ya hacemos en el Back End con Node.js!

Y también cambiemos el archivo `local.settings.json`. Este archivo es responsable de "almacenar" todas las claves que no queremos exponer al realizar el commit. Tenga en cuenta que este archivo está en la lista de archivos en `.gitignore`.

Abra el archivo `local.settings.json` y realice los siguientes cambios:

* **archivo: local.settings.json**

```json
{
  "IsEncrypted": false,
  "Values": {
    "FUNCTIONS_WORKER_RUNTIME": "node",
    "AzureWebJobsStorage": "{AzureWebJobsStorage}"
  },
  "Host": {
    "LocalHttpPort": 7071,
    "CORS": "*"
  }
}
```

Tenga en cuenta en el código anterior que ya estamos habilitando CORS. ¡Porque sin él, no podemos realizar operaciones CRUD en el Front-End! Si quieres entender un poco más sobre CORS te recomiendo leer **[AQUI](https://developer.mozilla.org/pt-BR/docs/Web/HTTP/Controle_Acesso_CORS)**.

Bueno, la primera parte está lista! ¡Ahora creemos nuestro CRUD en Azure Functions!

## Creando la función 'CreateFuncionario'

Para crear una nueva función, simplemente escriba el siguiente comando:

```bash
func new
```

Ingresar este comando le dará varias opciones de plantilla que Azure Functions pone a nuestra disposición. En nuestro caso, como ya se mencionó anteriormente, elija la plantilla: `HttpTrigger`. Siga los pasos del gif:

 [![gif-serverless-09.gif](https://s3.gifyu.com/images/gif-serverless-09.gif)](https://gifyu.com/image/hYI8)

Tenga en cuenta que se crearon una carpeta `CreateFuncionario` y dos archivos:


* **function.json**: Aquí definiremos las rutas y los métodos de nuestro endpoint.

* **index.json**: Aquí desarrollaremos la lógica del endpoint.

Comencemos a alterar estos archivos. Comenzando con `function.json`

* **archivo: CreateFuncionario/function.json**

```json
{
  "bindings": [{
          "authLevel": "anonymous",
          "type": "httpTrigger",
          "direction": "in",
          "name": "req",
          "methods": ["post"],
          "route": "funcionarios"
      },
      {
          "type": "http",
          "direction": "out",
          "name": "res"
      }
  ]
}
```


Ahora cambiemos el archivo `index.js`:

* **archivo: CreateFuncionario/index.js**

```javascript
/**
 * Arquivo: CreateFuncionario/index.js
 * Data: 10/11/2019
 * Descrição: arquivo responsável por criar um novo 'Funcionário'
 * Author: Glaucia Lemos
 */

const createMongoClient = require('../shared/mongo')

module.exports = async function (context, req) {
  const funcionario = req.body || {}

  if (funcionario) {
    context.res = {
      status: 400,
      body: 'Os dados do(a) Funcionário(a) é obrigatório!'
    }
  }

  const { db, connection } = await createMongoClient()

  const Funcionarios = db.collection('funcionarios')

  try {
    const funcionarios = await Funcionarios.insert(funcionario)
    connection.close()

    context.res = {
      status: 201,
      body: funcionarios.ops[0]
    }
  } catch (error) {
    context.res = {
      status: 500,
      body: 'Error ao criar um novo Funcionário(a)'
    }
  }
}

```

Aquí estamos definiendo prácticamente la ruta `POST` y desarrollando la lógica de Crear un nuevo Empleado.

Vamos a ejecutar este endpoint? Para ejecutar, simplemente escriba el siguiente comando:

```bash
> func host start
```

¡Y enumerará nuestro endpoint creado! Mira el gif:

[![gif-serverless-11.gif](https://s3.gifyu.com/images/gif-serverless-11.gif)](https://gifyu.com/image/hYI5)

Es el siguiente endpoint: `[POST] http://localhost:7071/api/funcionario`

La puerta `7071` es la puerta predeterminado para Azure Functions. ¡Y eso es exactamente lo que necesitaremos poner en nuestro Front End!

Bueno, ahora tomemos esta ruta y agréguela al Front End. Para esto necesitamos hacer algunos cambios al proyecto `Front`. Vaya a la carpeta `front` en:` front -> src -> app -> funcionario.service.ts` y cambie el siguiente archivo `funcionario.service.ts`

* **archivo: funcionario.service.ts**

```javascript
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class FuncionarioService {

  // ==> Uri da api (Back-End)
  uri = 'http://localhost:7071/api';

  constructor(private http: HttpClient) { }


(...)
```

Solo necesitamos cambiar el 'uri' definido en el service de Angular.

En este punto, necesitaremos ejecutar Mongo Compass y Front End. ¡Observe en el gif cómo persistirá el nuevo empleado y ya no necesitaremos la carpeta `api` del proyecto!

**(Haga clic en la imagen para mirar el gif)**

[![gif-serverless-122d9fa9f9e2c32e04.md.gif](https://s3.gifyu.com/images/gif-serverless-122d9fa9f9e2c32e04.md.gif)](https://gifyu.com/image/hYuM)

¡Persistió maravillosamente! 😍 

¡Ahora, hagamos la lista de empleados!

## Creando la función 'GetFuncionarios'

Es lo mismo que hicimos anteriormente, creemos una nueva función con el comando: `func new`, nombremos la función` GetFuncionarios` y cambiemos los archivos: `function.json` e` index.js`

**(Haga clic en la imagen para mirar el gif)**

[![gif-serverless-1390be8d86cc5d4218.md.gif](https://s3.gifyu.com/images/gif-serverless-1390be8d86cc5d4218.md.gif)](https://gifyu.com/image/hYuz)

- **GetFuncionarios/function.json**

```json
{
    "bindings": [{
            "authLevel": "anonymous",
            "type": "httpTrigger",
            "direction": "in",
            "name": "req",
            "methods": ["get"],
            "route": "funcionarios"
        },
        {
            "type": "http",
            "direction": "out",
            "name": "res"
        }
    ]
}

```


- **GetFuncionarios/index.js**

```javascript
/**
 * Arquivo: GetFuncionarios/index.js
 * Data: 10/11/2019
 * Descrição: arquivo responsável por listar todos os 'Funcionários'
 * Author: Glaucia Lemos
 */

const createMongoClient = require('../shared/mongo')

module.exports = async context => {
  const { db, connection } = await createMongoClient()


  const Funcionarios = db.collection('funcionarios')
  const res = await Funcionarios.find({})
  const body = await res.toArray()

  connection.close()

  context.res = {
    status: 200,
    body
  }
}
```

¡Intentémoslo de nuevo! ¡Mira el gif de nuevo!

[![gif-serverless-14.gif](https://s3.gifyu.com/images/gif-serverless-14.gif)](https://gifyu.com/image/hYdI)

De nuevo está funcionando perfectamente. Ya notó que es fácil crear un CRUD con Azure Functions, ¿no? ¡Ahora siga los mismos pasos para crear las prójimas funciones!

## Creando la función 'GetFuncionarioById'

Ahora que está muy claro para todos aquí lo fácil que es crear un CRUD con Azure Functions, comenzaré a acelerar el proceso de creación y solo informaré lo que ha cambiado en los archivos `function.json` e` index.js`

- **GetFuncionarioById/index.js**

```json
{
    "bindings": [{
            "authLevel": "anonymous",
            "type": "httpTrigger",
            "direction": "in",
            "name": "req",
            "methods": ["get"],
            "route": "funcionarios/{id}"
        },
        {
            "type": "http",
            "direction": "out",
            "name": "res"
        }
    ]
}
```

- **GetFuncionarioById/function.json**

```javascript
// @ts-nocheck
/**
 * Arquivo: GetFuncionarioById/index.js
 * Data: 10/11/2019
 * Descrição: arquivo responsável por listar Funcionário pelo Id
 * Author: Glaucia Lemos
 */

const { ObjectID } = require('mongodb')
const createMongoClient = require('../shared/mongo')

module.exports = async function (context, req) {
  const { id } = req.params

  if (!id) {
    context.res = {
      status: 400,
      body: 'Por favor, passe o número correto do Id do Funcionário!'
    }

    return
  }

  const { db, connection } = await createMongoClient()

  const Funcionarios = db.collection('funcionarios')

  try {
    const body = await Funcionarios.findOne({ _id: ObjectID(id) })

    connection.close()
    context.res = {
      status: 200,
      body
    }
  } catch (error) {
    context.res = {
      status: 500,
      body: 'Erro ao listar o Funcionário pelo Id.'
    }
  }
}
```

No probemos ahora. Desarrollemos las dos últimas funciones: `Update` y` Delete`.

## Creando la función 'UpdateFuncionario'

Una vez más, vamos a crear una nueva función y cambiar los archivos y `index.js` `function.json`:

- **UpdateFuncionario/index.js**

```json
{
    "bindings": [{
            "authLevel": "anonymous",
            "type": "httpTrigger",
            "direction": "in",
            "name": "req",
            "methods": ["put"],
            "route": "funcionarios/{id}"
        },
        {
            "type": "http",
            "direction": "out",
            "name": "res"
        }
    ]
}
```

- **UpdateFuncionario/index.js**

```javascript
// @ts-nocheck
/**
 * Arquivo: UpdateFuncionario/index.js
 * Data: 10/11/2019
 * Descrição: arquivo responsável por atualizar 'Funcionário' por Id
 * Author: Glaucia Lemos
 */

const { ObjectID } = require('mongodb')
const createMongoClient = require('../shared/mongo')

module.exports = async function (context, req) {
  const { id } = req.params
  const funcionario = req.body || {}

  if (!id || !funcionario) {
    context.res = {
      status: 400,
      body: 'Os campos são obrigatórios'
    }

    return
  }

  const { db, connection } = await createMongoClient()
  const Funcionarios = db.collection('funcionarios')

  try {
    const funcionarios = await Funcionarios.findOneAndUpdate(
      { _id: ObjectID(id) },
      { set: funcionario }
    )

    connection.close()

    context.res = {
      status: 200,
      body: funcionarios
    }
  } catch (error) {
    context.res = {
      status: 500,
      body: 'Erro ao atualizar o Funcionário'
    }
  }
}
```

Bueno. Ahora desarrollemos nuestra última función: `Delete`.

## Creando la función 'DeleteFuncionario'

Nuevamente, solo cree una nueva función, elija la opción: `HttpTrigger`, nombre la función` DeleteFuncionario` y cambie los archivos` function.json` e` index.js`:

- **DeleteFuncionario/function.json**

```json
{
  "bindings": [{
          "authLevel": "anonymous",
          "type": "httpTrigger",
          "direction": "in",
          "name": "req",
          "methods": ["delete"],
          "route": "funcionarios/{id}"
      },
      {
          "type": "http",
          "direction": "out",
          "name": "res"
      }
  ]
}
```

- **DeleteFuncionario/index.js**

```javascript
// @ts-nocheck
/**
 * Arquivo: DeleteFuncionario/index.js
 * Data: 10/11/2019
 * Descrição: arquivo responsável excluir um 'Funcionário' pelo Id
 * Author: Glaucia Lemos
 */

const { ObjectID } = require('mongodb')
const createMongoClient = require('../shared/mongo')

module.exports = async function (context, req) {
  const { id } = req.params

  if (!id) {
    context.res = {
      status: 400,
      body: 'Os campos são obrigatórios!'
    }

    return
  }

  const { db, connection } = await createMongoClient()

  const Funcionarios = db.collection('funcionarios')

  try {
    await Funcionarios.findOneAndDelete({ _id: ObjectID(id) })
    connection.close()
    context.res = {
      status: 204,
      body: 'Funcionário excluído com sucesso!'
    }
  } catch (error) {
    context.res = {
      status: 500,
      body: 'Erro ao excluir Funcionário' + id
    }
  }
}
```

¡Y nuestro CRUD está listo! Vamos a probar todos los endpoints? ¡Mira el gif!

**(Haga clic en la imagen para mirar el gif)**

[![gif-serverless-156824eb58eaca624e.md.gif](https://s3.gifyu.com/images/gif-serverless-156824eb58eaca624e.md.gif)](https://gifyu.com/image/hYnX)

Lo más hermoso no es así? Tenga en cuenta nuevamente, que la carpeta `api` donde hay numerosos archivos, ¡ya no la necesitará!

Todo el código desarrollado está aquí:

👉 **[Projeto Front-End](https://github.com/glaucia86/workshop-mean-serverless)**

👉 **[Projeto Api - Serverless](https://github.com/glaucia86/crud-serverless-mongodb)**

## Conclusión

Hoy hemos aprendido cómo migrar una aplicación MEAN a Azure Functions, pero persistiendo estos datos localmente y realizando estas funciones localmente. ¿Qué sucede si necesitamos hacer deploy de esta aplicación en la nube? ¿Y cómo sería nuestro backend?

En el próximo post, le explicaré cómo migrar de MongoDb a CosmosDb y cómo implementar estas funciones con una extensión de Azure Tools en Visual Studio Code.

Si desea conocer más detalles sobre Azure Functions, le recomiendo los siguientes cursos totalmente gratuitos de Serverless & Azure Functions y algunos otros recursos importantes:

✅ **[Cursos Grátis - Azure Functions](https://docs.microsoft.com/es-es/learn/paths/create-serverless-applications/?WT.mc_id=servsept_devto-blog-gllemos)**

✅ **[Azure para desarrolladores de JavaScript y Node.js](https://docs.microsoft.com/es-es/javascript/azure/?WT.mc_id=servsept_devto-blog-gllemos&view=azure-node-latest)**

✅ **[Documentación de Azure Functions](https://docs.microsoft.com/es-es/azure/azure-functions/?WT.mc_id=servsept_devto-blog-gllemos)**

✅ **[Creando su primera función mediante Visual Studio Code](https://docs.microsoft.com/es-es/azure/azure-functions/functions-create-first-function-vs-code?WT.mc_id=servsept_devto-blog-gllemos)**

✅ **[VS Code Extension – Azure Functions](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-azurefunctions&WT.mc_id=servsept_devto-blog-gllemos)**

✅ **[E-Book Grátis - Azure Serverless Computing Cookbook](https://azure.microsoft.com/es-es/resources/azure-serverless-computing-cookbook/?WT.mc_id=servsept_devto-blog-gllemos)**

Y para saber esta y otras novedades, ¡sígueme en twitter!

[![Twitter](https://code4coders.files.wordpress.com/2019/05/image-12.png)](https://twitter.com/glaucia_lemos86)

Hasta pronto! ❤️ ❤️ ❤️