143
Aula 7º
[Link] e MySQL
Olá,
Sejam bem-vindos(as) à penúltima aula da disciplina
Desenvolvimento Voltado à Web III. Na aula anterior,
os WebSocktes foram definidos e exemplificados. Eles
são ferramentas que garantem uma conexão bidirecional
permanente entre cliente e servidor, podendo ser utilizados em
chats e jogos online que demandam baixa latência na troca de
informações.
Nesta aula utilizaremos o [Link] para se conectar ao
banco de dados MySQL e efetuar operações de Seleção,
Inserção, Remoção e Atualização dos dados.
Boa aula!
Bons estudos!
Objetivos de aprendizagem
Ao término desta aula, vocês serão capazes de:
• construir uma API que retorna JSON;
• criar um CRUD com [Link] e MySQL.
144 Desenvolvimento Voltado a Web III 50
MySQL a partir da versão 8.0 você usa a senha padrão para
Seções de estudo o usuário root, o erro “ER_NOT_SUPPORTED_AUTH_
MODE” irá ocorrer.
Figura 1 – Erro Auth Mode Mysql.
1 – Usando o MySQL no [Link]
2 – O que é CRUD?
3 – Construindo uma API
1 - Usando o MySQL no [Link]
O MySQL é um SGBD publicado em 1995 pela
empresa MySQL AB, adquirida pela Sun Microsystem que
foi incorporada pela Oracle. Esta última mantém uma versão
gratuita que pode ser utilizada pela comunidade em geral.
Antes de iniciar a conexão do MySQL com o Node. Fonte: Acervo pessoal.
js é preciso que tenha o MySQL devidamente instalado. A
Oracle disponibiliza uma versão denominada Edição da ,VVR VLJQLÀFD TXH YRFr GHYH DOWHUDU D VHQKD SDGUmR GR
Comunidade, que quando instalada corretamente, possui o MySQL. Para isso você pode executar o seguinte comando
VHUYLGRUHXPDLQWHUIDFHJUiÀFDR0\64/:RUNEHQFK diretamente no MySQL Workbench.
Além disso, é importante ter um banco de dados criado
para que seja possível fazer os testes e criação da API,
$/7(586(5µURRW¶#¶ORFDOKRVW¶
como veremos mais adiante. Nos materiais de aula serão
IDENTIFIED WITH mysql_native_
disponibilizadas tutoriais para instalação do MySQL, além de
SDVVZRUG%<µ¶
um banco de dados de exemplo.
&RP WXGR LQVWDODGR FRQÀJXUDGR H SURQWR SRGHPRV
Dessa forma, o usuário root passará a usar a senha
iniciar a conexão do [Link] com o MySQL. Para instalar o
`123456789`, possibilitando a conexão com o MySQL.
módulo que irá fazer a comunicação entre nossa aplicação e o
MySQL utilizamos o seguinte comando no prompt.
Figura 2 – MySQL conectado.
npm install mysql --save
Esse módulo possui o driver do MySQL. Para usá-
los carregamos, então, o módulo para o nosso código e
instanciamos um objeto, que será a conexão com o MySQL,
através do método createConnection(), passando por
Fonte: Acervo pessoal.
parâmetros as informações de nosso banco de dados, tais
como, usuário, senha, banco de dados e host.
Depois que o [Link] conseguiu se conectar com sucesso
ao MySQL, podemos executar o SQL, seja ele qual for,
YDUP\VTO UHTXLUH µP\VTO¶
através do método query(), feito pelo objeto instanciado com
a conexão. Ao realizar o comando, a função que é retornada
var con = [Link]({
tem a possibilidade de tratar algum erro que possa ter dado
host: “localhost”,
nessa execução ou retornar o resultado do SQL no console.
user: “seuusuario”,
password: “suasenha”,
[Link](sql, function (err, result)
database: “seubancodedados”
{
});
if (err) throw err;
[Link](“Result: “ + result);
Feita a chamada para se criar a conexão ela irá disparar
um evento, o método connect(), que poderá tratar erros caso });
não tenha sido possível fazer a conexão com o MySQL.
[Link](function(err) {
22TXH«&58'"
if (err) throw err;
[Link](“Conectado!”); Create, Read, Update e Delete. A partir das letras iniciais
}); de cada uma dessas operações temos o acrônimo CRUD. Ele
trata das 4 operações básicas de SQL, Insert, Select, Update e
Um detalhe muito importante, se no seu banco de dados Delete, respectivamente.
51 145
Figura 3 – CRUD.
Fonte: Acervo pessoal.
Fonte: PIRES (2017).
O paradigma CRUD é muito utilizado na construção de
aplicações web, já que permite a manipulação completa do O mais importante da API é que ela contenha padrões.
banco de dados. Por exemplo, para construir um dicionário Devido a sua interoperabilidade, todas as aplicações devem
online, o que cada operação do CRUD deveria fazer?: saber como chamar a API, e o que esperar da resposta dela. A
resposta da API pode ser dada em formatos diferentes, pode
Create ser em XML, JSON, YAML. Enquanto o primeiro demanda
Responsável pela inserção de novas palavras, sua mais escrita, o segundo e o terceiro são muito mais leves e
GHÀQLomRHFODVVHJUDPiWLFDO$OpPGLVVRHVVDQRYDSDODYUD parecidos, como a forma que escrevemos diariamente.
WHUiXPDLGHQWLÀFDomR~QLFDTXHSRGHUiVHUXVDGDSDUDDFHVVDU
esse recurso posteriormente. Criar a palavra Abacaxi. XML
INSERT INTO palavras VALUES (‘Abacaxi’, ‘Planta <dicionario>
originária da América tropical.’, ‘Substantivo de dois gêneros’); <palavra>
Abacaxi
Read </palavra>
Tem por função retornar as palavras que já foram VLJQL¿FDGR!
inseridas no banco de dados, podendo ainda retornar um Planta originária da América
FRQMXQWRHVSHFtÀFRGHDFRUGRFRPDOJXPDFRQGLomRVHMDSRU tropical
VHX LG RX SHOR VHX QRPH 0RVWUDU R VLJQLÀFDGR GD SDODYUD VLJQL¿FDGR!
Abacaxi. <classegramatical>
6XEVWDQWLYRGHGRLVJrQHURV
6(/(&7VLJQL¿FDGR)520SDODYUDV:+(5( </classegramatical>
QRPH ¶$EDFD[L¶ </dicionario>
Update JSON
Atualiza um ou mais atributos de uma ou um conjunto {
de palavras a partir de uma condição. Atualizar a classe dicionário: {
gramatical da palavra Abacaxi. palavra: Abacaxi
UPDATE palavra SET classe=’Adjetivo de dois gêneros’ VLJQL¿FDGR 3ODQWD RULJLQiULD
WHERE nome=’Abacaxi’; da América tropical
classegramatical: Substantivo
Delete GHGRLVJrQHURV
Remove palavras do dicionário de acordo com uma }
condição. Delete a palavra Abacaxi. }
DELETE FROM palavra WHERE nome=’Abacaxi’;
Para cada uma das ações deve-se retornar o que foi YAML
exigido ou se foi possível ou não realizar o comando. dicionário:
palavra: Abacaxi
VLJQL¿FDGR 3ODQWD RULJLQiULD
3 - Construindo uma API da América tropical
classegramatical: Substantivo
Pires (2017) explica que uma API (Application GHGRLVJrQHURV
Programming Interface) é uma coleção de rotinas e padrões
desenvolvidos e documentados, que podem ser utilizados Algumas APIs permitem o retorno em várias
por outras aplicações, sem que estas precisem conhecer representações, sendo passado também por parâmetro a
a implementação detalhadamente. “APIs permitem uma representação desejada, por exemplo a API VIACEP que
interoperabilidade entre aplicações”. possibilita a consulta gratuita de CEPs Brasileiros, seja pelo
146 Desenvolvimento Voltado a Web III 52
número do CEP ou pelo endereço, como pode ser visto {
na documentação em [Link] Exemplo “name”: “api-vendas”,
de pesquisa com CEP em JSON ou XML: [Link]/ “version”: “1.0.0”,
ws/01001000/json/ ou [Link]/ws/01001000/xml/. “description”: “Criação de API
para o banco de dados VENDAS”,
“main”: “[Link]”,
Figura 5 – JSON x XML. “scripts”: {
“test”: “echo \”Error: no test
VSHFL¿HG?´ H[LW´
},
“author”: “Felipe Perez”,
“license”: “ISC”
};
Em seguida, é importante fazer a instalação dos módulos
que serão necessários, fazendo a chamada ao npm para
instalar os módulos de terceiros.
Fonte: Adaptado de [Link]/ . npm install string --save
npm install mysql --save
Vamos então começar a construção da nossa API, na npm install nodemon –save-dev
qual utilizaremos apenas o retorno no formato JSON. Para
facilitar, vamos aproveitar alguns módulos que já foram Após a instalação de cada um dos módulos, as
explicados em aulas anteriores, tais como, http, url e string. dependências são atualizadas então no arquivo [Link].
Vamos usar também um banco de dados de exemplo,
que tem como estrutura o diagrama da Figura 6. Nele já {
temos dados inseridos em todas as tabelas, possibilitando uma “name”: “api-vendas”,
melhor visualização dos resultados. “version”: “1.0.0”,
“description”: “Criação de API para
o banco de dados VENDAS”,
Figura 6 – Estrutura BD. “main”: “[Link]”,
“scripts”: {
“test”: “echo \”Error: no test
VSHFL¿HG?´ H[LW´
},
“author”: “Felipe Perez”,
“license”: “ISC”,
“dependencies”: {
³P\VTO´³A´
“string”: “^3.3.3”
},
“devDependencies”: {
“nodemon”: “^1.19.1”
}
}
'HÀQLPRV DJRUD TXH R DUTXLYR SULQFLSDO GH QRVVD
aplicação api-vendas é o [Link], que deve ser criado na pasta
raiz do aplicativo. No início desse arquivo iremos carregar
todos os módulos que serão utilizados.
FRQVWP\VTO UHTXLUH µP\VTO¶
FRQVWKWWS UHTXLUH µKWWS¶
Fonte: Acervo pessoal. FRQVWXUO UHTXLUH µXUO¶
FRQVW6 UHTXLUH µVWULQJ¶
Uma nova pasta deve ser criada e renomeada a seu
Como a nossa API vai manipular os dados do MySQL,
critério. Neste material a chamaremos de api-vendas. Dentro
GHYHPRVFULDUXPDFRQH[mRFRPR0\64/HYHULÀFDUVHIRL
dela fazemos uma chamada a npm init para construção do
conectado corretamente.
arquivo [Link], como visto na aula 04. Responderemos
as perguntas que forem solicitadas e o arquivo será preenchido var con = [Link]({
automaticamente com o seguinte resultado. host: “localhost”,
53 147
user: “root”, const server = http.
SDVVZRUG³´ createServer((request,response)=>{
database: “vendas” var q = [Link]([Link],
}); true);
var api = S([Link]).
[Link](function(err) { VSOLW/HIW µ¶
if (err) throw err; [Link](api);
[Link](“Conectado!”); [Link]([Link]);
}); });
A depender então da solicitação do usuário, a nossa API [Link](3000);
irá efetuar o que for pedido. Para isso, vamos criar um servidor
HTTP que irá receber as informações através do request e Após salvar o arquivo com as alterações acima, o
rotas serão criadas para cada uma das funções do CRUD. nodemon percebe a atualização e reinicia o servidor. Quando
Na URL para chamada, a API atenderá ao seguinte fazemos novamente a solicitação [Link]
padrão: cidade/?nome=Ponta Pora&estado=MS a forma de exibição
[Link] do pathname já foi alterada, agora podemos acessar cada valor
t i p o / t a b e l a / c o l u n a / por uma posição do array criado.
valor/?atributo1=valor1&atributo2=valor2
Figura 7 – splitLeft.
O pathname é responsável por informar ao servidor qual
rota ele deve seguir dentro do servidor e a query receberá
dados, quando necessário para inserção ou atualização no
banco de dados.
const server = http.
createServer((request,response)=>{
var q = [Link]([Link], Fonte: Acervo pessoal.
true);
[Link]([Link]); &RPRMiIRLGHÀQLGRRSDGUmRGDFKDPDGDDQRVVD$3,
[Link]([Link]); podemos atribuir a algumas variáveis, o valor das posições
}); relativas do array criado pelo pathname. Além disso, a função
[Link](3000); [Link]() transforma cada par de chave e valor passado
pela query como um array que pode ser acessado de sua
3DUDQmRWHUPRVTXHÀFDUH[HFXWDQGRRVHUYLGRUWRGDYH] posição.
em nossos testes, faremos uma chamada via nodemon para o
arquivo [Link], que será atualizado sempre que houver uma const server = http.
PRGLÀFDomRQDSDVWDGHVVHDUTXLYR&RPRVHUYLGRUGHVFULWR createServer((request,response)=>{
acima iniciado e fazendo uma chamada ao servidor com var q = [Link]([Link],
a URL [Link] true);
Pora&estado=MS o servidor recebe então uma request. var api = S([Link]).
A partir da [Link] o módulo url separa os dados VSOLW/HIW µ¶
contidos nela, e podem ser acessados diretamente como visto
na Figura 7. var tipo = api[1]; //get, set,
new ou delete
Figura 7 – URL. var tabela = api[2];
var coluna =
DSL>@ ´´ "XQGH¿QHGDSL>@
var valor = api[4];
var query = [Link](q.
query);
});
Fonte: Acervo pessoal.
[Link](3000);
No pathname os valores são divididos entre barras.
Pode-se manipular essas informações utilizando a função Já sabemos o que o cliente quer, agora precisamos projetar
.splitLeft(‘/’) do módulo string. Passamos por parâmetro qual as rotas que nosso servidor irá tomar dependendo do tipo que
a string que vai dividir os valores, no caso a barra, e ela nos foi enviado pelo cliente. Cada rota representará uma ação do
retorna um array com cada um dos valores em uma posição. CRUD. Começaremos pela mais simples de se implementar.
148 Desenvolvimento Voltado a Web III 54
Read Figura 9 – Select Where.
Para retornar o conteúdo de uma tabela para o cliente
ele deverá, pelo menos, passar para a API o nome da tabela
[Link] Ele pode ainda criar uma
condição passando mais dois parâmetros, fazendo com
que a API retorne exatamente um dos registros http://
localhost:3000/get/cidade/codcid/3.
Dentro do servidor é criado, então, um switch(tipo), que
de acordo com a solicitação vai percorrer e retornar um dos
FDVRVHVSHFtÀFRV&RPHoDQGRSHORFDVRWLSR JHW
Fonte: Acervo pessoal.
var sql;
[Link](‘Content- Create
W\SH¶¶DSSOLFDWLRQMVRQ¶ 3DUDDVRXWUDVDo}HVFULDUHPRVFDVRVHVSHFtÀFRVGHQWUR
switch(tipo){ do switch já criado. Para inserir um novo dado no banco
FDVHµJHW¶ de dados precisamos passar para a API o nome da tabela e
sql = “SELECT * FROM os dados que serão inseridos [Link]
“+tabela; cidade/?nomecid=Campinas&uf=SP.
sql +=
FDVHµQHZ¶
FROXQD XQGH¿QHG "´ :+(5( ³FROXQD´
var colunas = “”;
“+valor:””);
var valores = “”;
[Link](sql);
var cont=0;
c o n .
[Link]((each)=>{
TXHU\ VTO HUUUHVXOW¿HOGV !^
colunas+=(cont>0)?”,”:””;
[Link](JSON.
valores+=(cont>0)?”,”:””;
stringify(result));
colunas+=each[0];
[Link]();
YDORUHV ¶´¶HDFK>@¶´¶
});
cont++;
break;
});
}
sql = “INSERT INTO
“+tabela+”(“+colunas+”) VALUES
Uma variável para que o comando SQL referente a essa
(“+valores+”)”;
ação é criada para que possa ser utilizada em todos os casos
FRQTXHU\ VTO HUUUHVXOW¿HOGV !^
do switch. Em seguida, a resposta do tipo de conteúdo que o
r e s p o n s e . e n d ( J S O N .
cliente irá receber é setado também para todos os casos, já que
stringify(result));
todos retornarão um JSON.
[Link]();
O SELECT, então, é construído com o nome da tabela
});
que o cliente enviou. E se o campo coluna também for
break;
passado pelo cliente, a cláusula WHERE é adicionada para
UHWRUQDUXPGDGRHVSHFtÀFR As variáveis valores e colunas são preenchidas de acordo
com os parâmetros que forem enviados pela query, na url,
Figura 8 – Select. pela função forEach() que percorre cada dupla de chave-valor
criada anteriormente pelo [Link](). Com essas variáveis
é construído o comando SQL, que irá inserir o dado no banco.
O retorno serão as informações relativas à inserção em formato
JSON, tais como linhas afetadas, id inserido, status do servidor.
Figura 10 – Insert.
Fonte: Acervo pessoal. Fonte: Acervo pessoal.
55 149
Update cuidados, é claro, pois o registro, depois de deletado, não pode
A função para atualizar os dados no banco deve conter ser recuperado. Iremos implementar duas exclusões, uma
todos os parâmetros utilizados até agora, o nome da tabela, quando é passado um parâmetro para comparação http://
o campo e valor que será utilizado para selecionar um dado localhost:3000/delete/cliente/codcli/3 e outro para deletar
HVSHFtÀFRHDTXHU\FRQWHQGRRVYDORUHVTXHVHUmRDOWHUDGRV todas as instâncias que existirem no banco de dados http://
Caso o campo e o valor não sejam informados, todos os registros localhost:3000/delete/cliente, tomando muito cuidado com
da tabela terão seus valores atualizados. Para substituir somente esse último, antes de testar faça um backup do seu banco de
o conteúdo da cidade cujo código é 3 [Link] dados.
set/cidade/codcid/3?nomecid=Campinas&uf=SP ou para
substituir todos os estados por SP [Link] FDVHµGHOHWH¶
cidade/?uf=SP. sql = “DELETE FROM “+tabela;
VTO FROXQD XQGH¿QHG "´ :+(5(
FDVHµVHW¶ “+coluna+” = “+valor:””);
var valores = “”; [Link](sql);
var cont=0;
FRQTXHU\ VTO HUUUHVXOW¿HOGV !^
[Link]((each)=>{ r e s p o n s e . e n d ( J S O N .
valores+=(cont>0)?”, “:””; stringify(result));
valores+=each[0]+” = “; [Link]();
YDORUHV ¶´¶HDFK>@¶´¶ });
cont++; break;
});
sql = “UPDATE “+tabela+” SET “+ Esse trecho possui a mesma função do caso get,
valores; simplesmente deleta tudo ou, caso alguma condição seja
VTO FROXQD XQGH¿QHG "´ :+(5( passada nos parâmetros, remove apenas os registros que
“+coluna+” = “+valor:””); atendam à condição. Deletando, retornará também um JSON
FRQTXHU\ VTO HUUUHVXOW¿HOGV !^ com as informações sobre o que ocorreu no banco, como
r e s p o n s e . e n d ( J S O N . quantas linhas foram excluídas.
stringify(result)); Figura 12 – Delete.
[Link]();
});
break;
O preenchimento da variável valor se baseia no mesmo
método do Insert. Como a estrutura do UPDATE é um
pouco diferente do INSERT, algumas adaptações são feitas
para poder funcionar. Além disso, a cláusula WHERE tem o
mesmo funcionamento do SELECT com WHERE, a mesma
dinâmica foi aproveitada aqui. Na Figura 11, a url chamada
não passou um valor para a cláusula WHERE, afetando 19
linhas. Destas, 12 foram realmente atualizadas com os valores Fonte: Acervo pessoal.
novos.
Figura 11 – Update.
Retomando a aula
&KHJDPRVDRȴQDOGDV«WLPDDXOD9DPRVUHFRUGDU"
1 – Usando o MySQL no [Link]
Na primeira seção, a conexão com o MySQL foi
estabelecida com o [Link], e após isso foi possível executar
Fonte: Acervo pessoal. querys nele.
Delete 2 – O que é CRUD?
3RUÀPpLPSRUWDQWHLPSOHPHQWDUDIXQomRTXHSRGH
deletar registros no banco de dados, sempre tomando muitos Em seguida, foi descrito o que é CRUD, que é o
150 Desenvolvimento Voltado a Web III 56
acrônimo de Create, Read, Update e Delete, que são as ações
básicas que podem ser operadas no MySQL.
3 – Construindo uma API
Na última seção foi explicado passo a passo de como
construir uma API.
Vale a pena
Vale a pena ler
LECHETA, R R. Node Essencial, Novatec, 2012.
PEREIRA, C R. Aplicações web real-time com Node. js.
Editora Casa do Código, 2014.
PEREIRA, C R. Building APIs with Node. js. Apress,
2016.
RUBENS, J. Primeiros passos com [Link]. Editora Casa
do Código, 2017.
Vale a pena acessar
COPES, F. In: The [Link] Handbook, 2019.
Disponível em: <[Link]
ebooks/>. Acesso em: 20 mai. 2019.
DELBONO, E. In: [Link] Succinctly, 2016.
Disponível em: <[Link]
nodejs>. Acesso em: 20 mai. 2019.
NETO, W. In: Construindo APIs testáveis com
[Link], 2018. Disponível em: < [Link]
construindo-apis-testaveis-com-nodejs/>. Acesso em: 20
mai. 2019.
MYSQL. In: [Link] MySQL, 2019. Disponível em:
<[Link]
asp/>. Acesso em: 03 jun. 2019.
CRUD. In: What is CRUD?, 2019. Disponível em:
<[Link]
Acesso em: 03 jun. 2019.
PIRES, J. In: O que é API? REST e RESTful? Conheça
as definições e diferenças, 2017. Disponível em: <https://
[Link]/o-que-e-api-rest-e-restful/>. Acesso em 03
jun. 2019.
Minhas anotações