React + Node.js + Express + MySQL example: Build a CRUD App

De wikijoan
Salta a la navegació Salta a la cerca

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):

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