Crie uma API REST com Node.js e Express:conectando um banco de dados
No primeiro tutorial, Entendendo APIs RESTful, aprendemos o que é a arquitetura REST, quais são os métodos e respostas de solicitação HTTP e como entender um endpoint de API RESTful. No segundo tutorial, Como configurar um servidor de API Express, aprendemos como criar servidores com o
http
integrado do Node módulo e a estrutura Express, e como rotear o aplicativo que criamos para diferentes endpoints de URL. Atualmente, estamos usando dados estáticos para exibir informações do usuário na forma de um feed JSON quando o endpoint da API é atingido com um
GET
solicitação. Neste tutorial, vamos configurar um banco de dados MySQL para armazenar todos os dados, conectar-se ao banco de dados de nosso aplicativo Node.js e permitir que a API use o GET
, POST
, PUT
e DELETE
métodos para criar uma API completa. Instalação
Até este ponto, não usamos um banco de dados para armazenar ou manipular quaisquer dados, então vamos configurar um. Este tutorial usará o MySQL e, se você já tiver o MySQL instalado em seu computador, estará pronto para seguir para a próxima etapa.
Se você não tiver o MySQL instalado, poderá baixar o MAMP para macOS e Windows, que fornece um ambiente de servidor local e banco de dados gratuitos. Depois de fazer o download, abra o programa e clique em Iniciar servidores para iniciar o MySQL.
Além de configurar o próprio MySQL, queremos que o software GUI visualize o banco de dados e as tabelas. Para Mac, baixe SequelPro e para Windows baixe SQLyog. Depois de baixar e executar o MySQL, você pode usar o SequelPro ou SQLyog para se conectar ao
localhost
com o nome de usuário root
e senha root
na porta 3306
. Depois que tudo estiver configurado aqui, podemos seguir para a configuração do banco de dados para nossa API.
Configurando o banco de dados
Em seu software de visualização de banco de dados, adicione um novo banco de dados e chame-o de
api
. Certifique-se de que o MySQL esteja em execução ou você não poderá se conectar ao localhost
. Quando você tem a
api
banco de dados criado, mova-se para ele e execute a seguinte consulta para criar uma nova tabela. CREATE TABLE `users` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(30) DEFAULT '', `email` varchar(50) DEFAULT '', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Esta consulta SQL criará a estrutura de nossos
users
tabela. Cada usuário terá um ID de incremento automático, um nome e um endereço de e-mail. Também podemos preencher o banco de dados com os mesmos dados que estamos exibindo atualmente por meio de uma matriz JSON estática executando um
INSERT
inquerir. INSERT INTO users (name, email) VALUES ('Richard Hendricks', '[email protected]'), ('Bertram Gilfoyle', '[email protected]');
Não há necessidade de inserir o
id
campo, pois é auto-incremental. Neste ponto, temos a estrutura de nossa tabela, bem como alguns dados de amostra para trabalhar. Conectando ao MySQL
De volta ao nosso aplicativo, precisamos nos conectar ao MySQL a partir do Node.js para começar a trabalhar com os dados. Anteriormente, instalamos o
mysql
módulo npm, e agora vamos usá-lo. Crie um novo diretório chamado data e faça um config.js Arquivo.
Começaremos solicitando o
mysql
módulo em data/config.js . const mysql = require('mysql');
Vamos criar um
config
objeto que contém o host, usuário, senha e banco de dados. Isso deve se referir à api
banco de dados que criamos e usamos as configurações padrão do localhost. // Set database connection credentials const config = { host: 'localhost', user: 'root', password: 'root', database: 'api', };
Para maior eficiência, vamos criar um pool MySQL, que nos permite usar várias conexões ao mesmo tempo em vez de ter que abrir e fechar manualmente várias conexões.
// Create a MySQL pool const pool = mysql.createPool(config);
Por fim, exportaremos o pool do MySQL para que o aplicativo possa usá-lo.
// Export the pool module.exports = pool;
Você pode ver o arquivo de configuração do banco de dados completo em nosso repositório GitHub.
Agora que estamos nos conectando ao MySQL e nossas configurações estão completas, podemos passar a interagir com o banco de dados a partir da API.
Obtendo dados de API do MySQL
Atualmente, nosso
routes.js
arquivo está criando manualmente uma matriz JSON de usuários, que se parece com isso. const users = [{ ...
Como não usaremos mais dados estáticos, podemos excluir todo o array e substituí-lo por um link para nosso pool MySQL.
// Load the MySQL pool connection const pool = require('../data/config');
Anteriormente, o
GET
para os /users
path estava enviando os users
estáticos dados. Nosso código atualizado irá consultar o banco de dados para esses dados. Vamos usar uma consulta SQL para SELECT
tudo dos users
tabela, que se parece com isso. SELECT * FROM users
Aqui está o que nossos novos
/users
get route será semelhante, usando o pool.query()
método. // Display all users app.get('/users', (request, response) => { pool.query('SELECT * FROM users', (error, result) => { if (error) throw error; response.send(result); }); });
Aqui, estamos executando o
SELECT
query e, em seguida, enviar o resultado como JSON para o cliente por meio do /users
ponto final. Se você reiniciar o servidor e navegar até o /users
página, você verá os mesmos dados de antes, mas agora é dinâmico. Usando parâmetros de URL
Até agora, nossos endpoints têm sido caminhos estáticos, seja o
/
root ou /users
— mas e quando queremos ver dados apenas sobre um usuário específico? Precisaremos usar um endpoint variável. Para nossos usuários, podemos querer recuperar informações sobre cada usuário individual com base em seu ID exclusivo. Para fazer isso, usaríamos dois pontos (
:
) para denotar que é um parâmetro de rota. // Display a single user by ID app.get('/users/:id', (request, response) => { ... }); });
Podemos recuperar o parâmetro para este caminho com o
request.params
propriedade. Como o nosso se chama id
, é assim que nos referimos a ele. const id = request.params.id;
Agora vamos adicionar um
WHERE
cláusula para nosso SELECT
para obter apenas resultados que tenham o id
especificado . Usaremos
?
como um espaço reservado para evitar injeção de SQL e passar o id como parâmetro, em vez de construir uma string concatenada, que seria menos segura. pool.query('SELECT * FROM users WHERE id = ?', id, (error, result) => { if (error) throw error; response.send(result); });
O código completo para nosso recurso de usuário individual agora se parece com isso:
// Display a single user by ID app.get('/users/:id', (request, response) => { const id = request.params.id; pool.query('SELECT * FROM users WHERE id = ?', id, (error, result) => { if (error) throw error; response.send(result); }); });
Agora você pode reiniciar o servidor e navegar até
https://localhost/users/2
para ver apenas as informações de Gilfoyle. Se você receber um erro como Cannot GET /users/2
, significa que você precisa reiniciar o servidor. Ir para este URL deve retornar um único resultado.
[{ id: 2, name: "Bertram Gilfoyle", email: "[email protected]" }]
Se é isso que você vê, parabéns:você configurou com sucesso um parâmetro de rota dinâmica!
Enviando uma solicitação POST
Até agora, tudo o que temos feito usou
GET
solicitações de. Essas solicitações são seguras, o que significa que não alteram o estado do servidor. Estamos simplesmente visualizando dados JSON. Agora vamos começar a tornar a API realmente dinâmica usando um
POST
pedido para adicionar novos dados. Mencionei anteriormente no artigo Understanding REST que não usamos verbos como
add
ou delete
na URL para realizar ações. Para adicionar um novo usuário ao banco de dados, POST
para o mesmo URL de onde os visualizamos, mas apenas configure uma rota separada para ele. // Add a new user app.post('/users', (request, response) => { ... });
Observe que estamos usando
app.post()
em vez de app.get()
agora. Como estamos criando em vez de ler, usaremos um
INSERT
query aqui, assim como fizemos na inicialização do banco de dados. Enviaremos todo o request.body
até a consulta SQL. pool.query('INSERT INTO users SET ?', request.body, (error, result) => { if (error) throw error;
Também vamos especificar o status da resposta como
201
, que significa Created
. Para obter o id do último item inserido, usaremos o insertId
propriedade. response.status(201).send(`User added with ID: ${result.insertId}`);
Todo o nosso
POST
código de recebimento ficará assim. // Add a new user app.post('/users', (request, response) => { pool.query('INSERT INTO users SET ?', request.body, (error, result) => { if (error) throw error; response.status(201).send(`User added with ID: ${result.insertId}`); }); });
Agora podemos enviar um
POST
pedido através. Na maioria das vezes, quando você envia um POST
solicitação, você está fazendo isso por meio de um formulário da web. Aprenderemos como configurar isso no final deste artigo, mas a maneira mais rápida e fácil de enviar um teste POST
é com cURL, usando o -d (--data)
bandeira. Vamos executar
curl -d
, seguido por uma string de consulta contendo todos os pares de chave/valor e o endpoint da solicitação. curl -d "name=Dinesh Chugtai&[email protected]" http://localhost:3002/users
Depois de enviar essa solicitação, você deve obter uma resposta do servidor.
User added with ID: 3
Se você navegar para
http://localhost/users
, você verá a última entrada adicionada à lista. Enviando uma solicitação PUT
POST
é útil para adicionar um novo usuário, mas usaremos PUT
para modificar um usuário existente. PUT
é idempotente, o que significa que você pode enviar a mesma solicitação várias vezes e apenas uma ação será executada. Isso é diferente de POST
, porque se enviássemos nossa nova solicitação de usuário mais de uma vez, ela continuaria criando novos usuários. Para nossa API, vamos configurar
PUT
para lidar com a edição de um único usuário, então vamos usar o :id
parâmetro de rota desta vez. Vamos criar um
UPDATE
query e certifique-se de que se aplica apenas ao id solicitado com o WHERE
cláusula. Estamos usando dois ?
placeholders, e os valores que passamos irão em ordem sequencial. // Update an existing user app.put('/users/:id', (request, response) => { const id = request.params.id; pool.query('UPDATE users SET ? WHERE id = ?', [request.body, id], (error, result) => { if (error) throw error; response.send('User updated successfully.'); }); });
Para nosso teste, editaremos o usuário
2
e atualize o endereço de e-mail de [email protected] para [email protected]. Podemos usar cURL novamente, com o [-X (--request)]
sinalizador, para especificar explicitamente que estamos enviando uma solicitação PUT. curl -X PUT -d "name=Bertram Gilfoyle" -d "[email protected]" http://localhost:3002/users/2
Certifique-se de reiniciar o servidor antes de enviar a solicitação, ou então você receberá o
Cannot PUT /users/2
erro. Você deve ver isso:
User updated successfully.
Os dados do usuário com id
2
agora deve ser atualizado. Enviando uma solicitação DELETE
Nossa última tarefa para completar a funcionalidade CRUD da API é fazer uma opção para excluir um usuário do banco de dados. Esta solicitação usará o
DELETE
Consulta SQL com WHERE
, e excluirá um usuário individual especificado por um parâmetro de rota. // Delete a user app.delete('/users/:id', (request, response) => { const id = request.params.id; pool.query('DELETE FROM users WHERE id = ?', id, (error, result) => { if (error) throw error; response.send('User deleted.'); }); });
Podemos usar
-X
novamente com cURL para enviar a exclusão. Vamos excluir o último usuário que criamos. curl -X DELETE http://localhost:3002/users/3
Você verá a mensagem de sucesso.
User deleted.
Navegue até
http://localhost:3002
, e você verá que há apenas dois usuários agora. Parabéns! Neste ponto, a API está concluída. Visite o repositório do GitHub para ver o código completo para routes.js .
Enviando solicitações por meio da request
Módulo
No início deste artigo, instalamos quatro dependências, e uma delas foi a
request
módulo. Em vez de usar solicitações cURL, você pode criar um novo arquivo com todos os dados e enviá-lo. Vou criar um arquivo chamado post.js que criará um novo usuário via POST
. const request = require('request'); const json = { "name": "Dinesh Chugtai", "email": "[email protected]", }; request.post({ url: 'http://localhost:3002/users', body: json, json: true, }, function (error, response, body) { console.log(body); });
Podemos chamar isso usando
node post.js
em uma nova janela de terminal enquanto o servidor estiver em execução e terá o mesmo efeito que usar cURL. Se algo não estiver funcionando com cURL, o request
module é útil, pois podemos visualizar o erro, a resposta e o corpo. Enviando solicitações por meio de um formulário da Web
Normalmente,
POST
e outros métodos HTTP que alteram o estado do servidor são enviados usando formulários HTML. Neste exemplo muito simples, podemos criar um index.html arquivo em qualquer lugar e crie um campo para um nome e endereço de e-mail. A ação do formulário apontará para o recurso, neste caso http//localhost:3002/users
, e especificaremos o método como post
. Crie index.html e adicione o seguinte código a ele:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Node.js Express REST API</title> </head> <body> <form action="http://localhost:3002/users" method="post"> <label for="name">Name</label> <input type="text" name="name"> <label for="email">Email</label> <input type="email" name="email"> <input type="submit"> </form> </body> </html>
Abra este arquivo HTML estático em seu navegador, preencha-o e envie-o enquanto o servidor estiver sendo executado no terminal. Você deve ver a resposta de
User added with ID: 4
, e você poderá ver a nova lista de usuários.