Criando uma API REST com Node.js e um Banco de Dados Oracle. Parte 3

Parte 3. Criando uma API REST: manipulando solicitações GET


No artigo anterior, você estabeleceu uma conexão com o banco de dados.

No mesmo, adicione a lógica de roteamento, controlador e banco de dados para manipular a solicitação HTTP GET no terminal da API "funcionários".

Adicionando lógica de roteamento


O Express é enviado com a classe Router , que simplifica o roteamento de solicitações HTTP para a lógica apropriada do controlador. Os caminhos de rota definem os pontos finais de um URL da API e podem conter parâmetros de rota que capturam valores em um URL.

Existem várias maneiras de determinar as rotas para o seu aplicativo. Por exemplo, quando o aplicativo é iniciado, você pode ler todos os arquivos no diretório do controlador e gerar automaticamente a lógica de roteamento com base em algumas regras predefinidas, como os nomes e as propriedades que eles fornecem. Como alternativa, você pode adicionar o arquivo ao diretório de configuração e lê-lo na inicialização.

Nesta aplicação, você usará uma abordagem de nível um pouco mais baixo, definindo programaticamente as rotas através do novo módulo roteador. Crie um novo arquivo chamado router.js no diretório de serviços . Adicione o seguinte código ao arquivo e salve as alterações.

const express = require('express'); const router = new express.Router(); const employees = require('../controllers/employees.js'); router.route('/employees/:id?') .get(employees.get); module.exports = router; 

O módulo roteador inicia solicitando o módulo Express e cria uma nova instância da classe Router Express. O método de rota do módulo roteador é usado para determinar a rota com base nos dados transmitidos. O caminho inclui um parâmetro opcional (devido a um ponto de interrogação) chamado id. A rota retornada do roteador possui métodos que correspondem aos métodos HTTP e permitem que os manipuladores sejam definidos. Nesse caso, o método get é usado para mapear a solicitação GET recebida para a função get definida no controlador do funcionário (que será criado abaixo).

No momento você possui um roteador, mas ele não é usado no aplicativo. Para usá-lo, abra o arquivo services / web-server.js e exclua a linha na parte superior, que requer um módulo de banco de dados (ele foi usado apenas para testes na postagem anterior ). Adicione a seguinte linha de código em seu lugar.

 // *** line that requires ../config/web-server.js is here *** const router = require('./router.js'); 

Em seguida, use o código a seguir para substituir todo o manipulador app.get, que responde às solicitações GET usando o módulo de banco de dados (todas as 7 linhas).

 // *** line that adds morgan to app here *** // Mount the router at /api so all its routes start with /api app.use('/api', router); 

Agora, o roteador é solicitado no módulo de serviço da web e é "montado" em / api. Isso significa que a URL completa para o terminal do funcionário será http: // server: port / api / employee /: id.

Adicionando lógica do controlador


A lógica do controlador entrará em operação a partir do momento em que o URL do terminal e o método HTTP forem conhecidos. Como o servidor da Web é construído usando o Express, a lógica do controlador será determinada usando middleware ou funções especiais que têm acesso a objetos de solicitação e resposta, bem como à próxima função.

A função de middleware utilizará a entrada do objeto de solicitação para gerar uma resposta que é enviada ao objeto de resposta. A próxima função é normalmente usada para chamar a próxima função de middleware no pipeline. No entanto, nesta API, a lógica do controlador será a última etapa no pipeline e concluirá a resposta HTTP. A próxima função será chamada somente se ocorrer um erro que passe o controle para o manipulador de erros Express padrão.

Vá para o diretório de controladores e crie um novo arquivo chamado employee.js . Copie e cole o seguinte código no arquivo e salve as alterações.

 /*01*/const employees = require('../db_apis/employees.js'); /*02*/ /*03*/async function get(req, res, next) { /*04*/ try { /*05*/ const context = {}; /*06*/ /*07*/ context.id = parseInt(req.params.id, 10); /*08*/ /*09*/ const rows = await employees.find(context); /*10*/ /*11*/ if (req.params.id) { /*12*/ if (rows.length === 1) { /*13*/ res.status(200).json(rows[0]); /*14*/ } else { /*15*/ res.status(404).end(); /*16*/ } /*17*/ } else { /*18*/ res.status(200).json(rows); /*19*/ } /*20*/ } catch (err) { /*21*/ next(err); /*22*/ } /*23*/} /*24*/ /*25*/module.exports.get = get; 

Linha 1: API do banco de dados dos funcionários (a ser criada abaixo).
Linhas 3-23: Uma função assíncrona chamada get é declarada. O bloco try-catch é usado no corpo da função para capturar as exceções lançadas no encadeamento principal e passá-las para a próxima função.
Linhas 5-7: uma constante com um contexto nomeado é declarada - este é um objeto universal que conterá propriedades relacionadas ao método de pesquisa da API do banco de dados. A propriedade id é adicionada ao contexto com base no valor que vem através de req.params.id.
Linha 9: o método find é usado para recuperar os registros de funcionários apropriados no banco de dados.
Linhas 11-19: A lógica condicional é usada para determinar o código de status HTTP correto e o corpo da resposta. Se um funcionário foi solicitado, mas não encontrado, o código de erro "404 não encontrado" é enviado como resposta. Caso contrário, um código 200 OK é enviado junto com o corpo de resposta baseado em JSON.
Linha 25: exportação de módulo para que você possa adicionar a outros módulos

O objeto req.params é apenas uma das várias propriedades usadas para obter dados de um objeto de solicitação recebido . Outras propriedades comuns incluem req.query para valores de sequência de caracteres de consulta na URL, req.body para o corpo da solicitação e req.cookies. Cabeçalhos HTTP podem ser obtidos usando o método req.get.

Adicionando lógica do banco de dados


Para iniciar o módulo de banco de dados de funcionários, acesse o diretório db_apis e crie um novo arquivo chamado employee.js . Adicione o seguinte código ao arquivo.

 const database = require('../services/database.js'); const baseQuery = `select employee_id "id", first_name "first_name", last_name "last_name", email "email", phone_number "phone_number", hire_date "hire_date", job_id "job_id", salary "salary", commission_pct "commission_pct", manager_id "manager_id", department_id "department_id" from employees`; async function find(context) { let query = baseQuery; const binds = {}; if (context.id) { binds.employee_id = context.id; query += `\nwhere employee_id = :employee_id`; } const result = await database.simpleExecute(query, binds); return result.rows; } module.exports.find = find; 

O módulo de banco de dados de funcionários apresenta um módulo de banco de dados comum e inicializa uma constante denominada baseQuery para a consulta SQL na tabela de funcionários. Os aliases de coluna com aspas duplas são usados ​​para controlar o caso das chaves retornadas.

Em seguida, é declarada uma função chamada find, que é usada para executar a consulta e retornar as linhas extraídas. Se o parâmetro de contexto passado tiver um valor de ID verdadeiro, a cláusula where será adicionada à solicitação, para que apenas um funcionário seja retornado.

Observe que o valor context.id não foi adicionado diretamente à solicitação. Em vez disso, um espaço reservado chamado: employee_id foi usado - isso é chamado de variável de ligação . O uso de variáveis ​​de ligação ao banco de dados Oracle é muito importante em termos de segurança e desempenho. O valor da variável de ligação é atribuído ao objeto de ligações, que é passado junto com a consulta para database.simpleExecute. Finalmente, as linhas recuperadas do banco de dados são retornadas ao chamador.

Inicie o aplicativo e acesse o navegador em http: // localhost: 3000 / api / employee. Você deve ver uma lista de funcionários da seguinte maneira (eu desmoronei alguns):
imagem
Você pode selecionar um funcionário adicionando um identificador ao final da URL, por exemplo: http: // localhost: 3000 / api / employee / 100.

imagem

Nesse ponto, sua API pode lidar com solicitações GET no terminal dos funcionários. Na próxima postagem, você estenderá a funcionalidade CRUD adicionando lógica que processa solicitações POST, PUT e DELETE.

Source: https://habr.com/ru/post/pt473350/


All Articles