Alternar do Express.js para o Azure Functions

O Express.js é uma das estruturas de Node.js mais populares para desenvolvedores da Web e continua sendo uma opção excelente para a criação de aplicativos que atendem aos pontos de extremidade da API.

Ao migrar o código para uma arquitetura sem servidor, a refatoração de pontos de extremidade Express.js afeta as seguintes áreas:

  • Middleware: o Express.js apresenta uma coleção robusta de middleware. Muitos módulos de middleware não são mais necessários para o Azure Functions e as funcionalidades do Gerenciamento de API do Azure. Verifique se você pode replicar ou substituir qualquer lógica tratada pelo middleware essencial antes de migrar os pontos de extremidade.

  • APIs diferentes: a API usada para processar as solicitações e as respostas difere entre o Azure Functions e o Express.js. O exemplo a seguir detalha as alterações necessárias.

  • Rota padrão: por padrão, os pontos de extremidade do Azure Functions são expostos sob a rota api. As regras de roteamento são configuráveis por meio de routePrefix no arquivohost.jsno.

  • Configuração e convenções: um aplicativo de funções usa o arquivo function.json para definir verbos HTTP, definir políticas de segurança e pode configurar a entrada e a saídada função. Por padrão, o nome da pasta que contém os arquivos de função define o nome do ponto de extremidade, mas você pode alterar o nome por meio da propriedade route no arquivo function.json.

Exemplo

Express.js

O exemplo a seguir mostra um ponto de extremidade GET de Express.js típico.

// server.js
app.get('/hello', (req, res) => {
  try {
    res.send("Success!");
  } catch(error) {
    const err = JSON.stringify(error);
    res.status(500).send(`Request error. ${err}`);
  }
});

Quando uma solicitação GET é enviada para /hello, uma resposta HTTP 200 que contém Success é retornada. Se o ponto de extremidade encontrar um erro, a resposta será um HTTP 500 com os detalhes do erro.

Funções do Azure

O Azure Functions organiza os arquivos de configuração e de código em uma única pasta para cada função. Por padrão, o nome da pasta determina o nome da função.

Por exemplo, uma função chamada hello tem uma pasta com os arquivos a seguir.

| - hello
|  - function.json
|  - index.js

O exemplo a seguir implementa o mesmo resultado que o ponto de extremidade de Express.js acima, mas com o Azure Functions.

// hello/index.js
module.exports = async function (context, req) {
  try {
    context.res = { body: "Success!" };
  } catch(error) {
    const err = JSON.stringify(error);
    context.res = {
      status: 500,
      body: `Request error. ${err}`
    };
  }
};

Ao migrar para o Functions, as seguintes alterações são feitas:

  • Módulo: O código da função é implementado como um módulo JavaScript.

  • Objeto de contexto e resposta: o context permite que você se comunique com o runtime da função. No contexto, você pode ler dados de solicitação e definir a resposta da função. O código síncrono exige que você chame context.done() 1.x para concluir a execução, enquanto as funções async 2.x+ resolvem a solicitação implicitamente.

  • Convenção de nomenclatura: o nome da pasta usado para conter os arquivos do Azure Functions é usado como o nome do ponto de extremidade por padrão (isso pode ser substituído na function.json).

  • Configuração: você define os verbos HTTP no arquivo function.json como POST ou PUT.

O seguinte arquivo function.json contém informações de configuração para a função.

{
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": ["get"]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    }
  ]
}

Ao definir get na matriz methods, a função está disponível para solicitações GET HTTP. Se você desejar que sua API aceite solicitações POST de suporte, também é possível adicionar post a matriz.

Próximas etapas