React + Node.js + Express + MySQL example: Build a CRUD App
Contingut
Introducció
Seguim aquests dos tutorials:
React + Node.js + Express + MySQL example: Build a CRUD App:
Node.js Rest APIs example with Express, Sequelize & MySQL: (backend)
Desenvolupament
S'ha seguit aquests dos tutorials, corresponent a la part del backen i del frontend (amb React). No hi ha hagut especials problemes per seguir els tutorials i fer-ho funcionar tot.
A continuació van unes notes del professor, que poden servir d'ajuda.
La base de dades ha d'estar creada (el codi no la crea). Nosaltres utilitzem la base de dades jbalmes.
fitxer db.config.js:
module.exports = {
HOST: "localhost",
USER: "root",
PASSWORD: "*******",
DB: "jbalmes",
dialect: "mysql",
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
}
};
$ node server.js
internal/modules/cjs/loader.js:638
throw err;
^
Error: Cannot find module 'cors'
Instal·lem el mòdul cors:
$ npm install cors
Error: Cannot find module './app/routes/turorial.routes'
hi ha un petit error en el tutorial: ha de ser tutorial.routes i no turorial.routes, en el server.js:
require("./app/routes/tutorial.routes")(app);
Primer de tot, mirar com es creen les taules quan arrenquem el servidor:
$ node server.js (node:24332) [SEQUELIZE0004] DeprecationWarning: A boolean value was passed to options.operatorsAliases. This is a no-op with v5 and should be removed. Server is running on port 8080. Executing (default): DROP TABLE IF EXISTS `tutorials`; Executing (default): DROP TABLE IF EXISTS `tutorials`; Executing (default): CREATE TABLE IF NOT EXISTS `tutorials` (`id` INTEGER NOT NULL auto_increment , `title` VARCHAR(255), `description` VARCHAR(255), `published` TINYINT(1), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB; Executing (default): SHOW INDEX FROM `tutorials` Drop and re-sync db.
I ja podem anar al mysql i comprovar que les taules s'han creat correctament.
Ara ja podem testejar la API
Per fer-ho es recomana utilitzar Postman (per a windows, suposo), però jo tinc experiència i em va bé utilitzant la utilitat en línia de comanda curl:
1. Create a new Tutorial using POST /tutorials Api
$ curl -i -H "Accept: application/json" -X POST -H "Content-Type: application/json" -d '{ "title":"Titol1","description":"Descripció 1" }' localhost:8080/api/tutorials
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: http://localhost:8081
Vary: Origin
Content-Type: application/json; charset=utf-8
Content-Length: 151
ETag: W/"97-RkimZsWUw8GCdReyYgVuLFXsxC8"
Date: Sat, 01 May 2021 21:43:51 GMT
Connection: keep-alive
{"id":1,"title":"Titol1","description":"Descripció 1","published":false,"updatedAt":"2021-05-01T19:07:19.204Z","createdAt":"2021-05-01T19:07:19.204Z"}
i efectivament, ho comprovem directament en el mysql:
mysql> select * from tutorials; +----+--------+---------------+-----------+---------------------+---------------------+ | id | title | description | published | createdAt | updatedAt | +----+--------+---------------+-----------+---------------------+---------------------+ | 1 | Titol1 | Descripció 1 | 0 | 2021-05-01 19:07:19 | 2021-05-01 19:07:19 | +----+--------+---------------+-----------+---------------------+---------------------+
Està funcionant la API.
2. Retrieve all Tutorials using GET /tutorials Api
$ curl -i -X GET localhost:8080/api/tutorials
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: http://localhost:8081
Vary: Origin
Content-Type: application/json; charset=utf-8
Content-Length: 761
ETag: W/"2f9-3kntDat4Q6ay4VVBoijKdyLkqls"
Date: Sat, 01 May 2021 19:15:34 GMT
Connection: keep-alive
[{"id":1,"title":"Titol1","description":"Descripció 1","published":false,"createdAt":"2021-05-01T19:07:19.000Z","updatedAt":"2021-05-01T19:07:19.000Z"},{"id":2,"title":"Titol2","description":"Descripció 2","published":false,"createdAt":"2021-05-01T19:09:26.000Z","updatedAt":"2021-05-01T19:09:26.000Z"},{"id":3,"title":"Titol3","description":"Descripció 3","published":false,"createdAt":"2021-05-01T19:09:35.000Z","updatedAt":"2021-05-01T19:09:35.000Z"},{"id":4,"title":"Titol4","description":"Descripció 4","published":false,"createdAt":"2021-05-01T19:09:42.000Z","updatedAt":"2021-05-01T19:09:42.000Z"},{"id":5,"title":"Titol5","description":"Descripció 5","published":false,"createdAt":"2021-05-01T19:09:50.000Z","updatedAt":"2021-05-01T19:09:50.000Z"}]
3. Retrieve a single Tutorial by id using GET /tutorials/:id Api
$ curl -i localhost:8080/api/tutorials/2
...
{"id":2,"title":"Titol2","description":"Descripció 2","published":false,"createdAt":"2021-05-01T19:09:26.000Z","updatedAt":"2021-05-01T19:09:26.000Z"}
4. Update a Tutorial using PUT /tutorials/:id Api
$ curl -i -H "Accept: application/json" -X PUT -H "Content-Type: application/json" -d '{ "published":"true"}' localhost:8080/api/tutorials/3
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: http://localhost:8081
Vary: Origin
Content-Type: application/json; charset=utf-8
Content-Length: 48
ETag: W/"30-eLrskyV5K+qpOebje/ICJS9bwCQ"
Date: Sat, 01 May 2021 21:41:52 GMT
Connection: keep-alive
{"message":"Tutorial was updated successfully."}
5. Find all Tutorials which title contains ‘node’: GET /tutorials?title=node
$ curl -i -X GET localhost:8080/api/tutorials/title=4
(no funciona?)
6. Find all published Tutorials using GET /tutorials/published Api
$ curl -i -X GET localhost:8080/api/tutorials/published
...
[{"id":3,"title":"Titol3","description":"Descripció 3","published":true,"createdAt":"2021-05-01T19:09:35.000Z","updatedAt":"2021-05-01T21:41:52.000Z"}]
7. Delete a Tutorial using DELETE /tutorials/:id Api
$ curl -i -X DELETE localhost:8080/api/tutorials/5
...
{"message":"Tutorial was deleted successfully!"}
8. Delete all Tutorials using DELETE /tutorials Api
$ curl -i -X DELETE localhost:8080/api/tutorials
...
{"message":"5 Tutorials were deleted successfully!"}
Front-end
I ara que ja tinc el servidor Node i tota la API REST, ara ja puc continuar amb el frontend, que recordem serà React.
La part del client la podem fer amb Redux o sense Redux
Sense Redux, continuem llegint l'article:
Amb Redux:
De moment ho fem sense redux:
Open cmd at the folder you want to save Project folder, run command:
$ npx create-react-app react-crud
És a dir, ho de moment tinc el directori ~/M06_WEC_2021/UF2/nodejs-express-sequelize-mysql i d'aquí penja server.js i app/
Creo el directori (no cal...) ~/M06_WEC_2021/UF2/nodejs-express-sequelize-mysql-FE
$ cd ~/M06_WEC_2021/UF2/nodejs-express-sequelize-mysql-FE $ npx create-react-app react-crud
És a dir, la idea del projecte és que tinc una carpeta per al back-end, i una carpeta per al front-end. Les dues carpetes poden penjar de la mateixa carpeta de projecte, aquí cadascú s'ha d'organitzar com vulgui.
cd react-crud cd src mkdir components cd components touch add-tutorial.component.js touch tutorial.component.js touch tutorials-list.component.js cd .. mkdir services cd services touch tutorial.service.js cd ..
Llibreries que necessitem instal·lar:
npm install bootstrap npm install react-router-dom. npm install axios
You can continue with step by step to implement this React App in the post. Hi ha vàries possibilitats:
Using React sense Redux (sense Hooks o amb Hooks):
- React.js CRUD example to consume Web API: https://bezkoder.com/react-crud-web-api/
- React Hooks CRUD example to consume Web API
Using React with Redux (sense Hooks o amb Hooks):
- React Redux CRUD example with Rest API
- React Hooks + Redux: CRUD example with Rest API
Nosaltres ho farem a pèl (sense Redux i sense Hooks) (Hooks és una ampliació de React que té una sèrie d'avantatges). Agafo la primera possibilitat, i seguim:
El front-end funciona pel port 8081 (recordem que el servidor està arrencat, i que funciona pel port 8080).
Finalment,
$ npm start Failed to compile. ./src/index.js Module not found: Can't resolve './serviceWorker' in '/home/joan/M06_WEC_2021/UF2/nodejs-express-sequelize-mysql-FE/react-crud/src'
i com es comenta en els comentaris de la pàgina a baix de tot, això es soluciona comentant a index.js les dues línies que fa referència a serviceWorker.
I ara sí que ja funciona:
$ npm start Compiled successfully! You can now view react-crud in the browser. Local: http://localhost:8081 On Your Network: http://192.168.1.67:8081 Note that the development build is not optimized. To create a production build, use yarn build.
Ja tenim una aplicació CRUD feta amb React com a front-end, i en el back-end tenim una API Rest amb Express (NodeJS) i MySQL com a bases de dades.
Continuació: altres backends, Laravel, Symfony PHP
Pots deixar el front-end tal com està, i implementar la mateixa API Rest amb el back-end que tu vulguis. L'aplicatiu funcionarà de la mateixa manera.
creat per Joan Quintana Compte, maig 2021