Ovaj blog post je nastavak prošlog u kojemu smo izradili jednostavan RESTful API koristeći Node.js i Express.js.
Ondje smo imali tablicu sa korisnicima i upravljali jednostavnom formom s dva tekstualna polja tj. kroz API smo dodavali ime i prezime korisnika, uređivali ih i brisali. U ovom primjeru API-ju ćemo dodati mogućnost dodavanja datoteka koje će se spremati na disk.
Kako bi jednostavnije mogli pratiti sadržaj ovog blog posta preuzmite API iz prošlog blog posta.
Početna struktura projekta:
1 2 3 4 5 6 7 |
| - KorisniciAPI/ | - node_modules/ | - body-parser/ | - express/ | - mysql/ | - server.js | - package.json |
Nadogradnja MySQL baze
Za početak ćemo dodati dva nova polja u bazu, k_slika i k_dokument, koja će nam služiti za povezivanje datoteka s određenim korisnikom. U oba polja će se spremati putanje do datoteka, iako sliku možemo spremati i kao base64 string, ali kako to nije najbolja praksa nećemo to raditi.
multer middleware
Kako bi API razumio što mu želimo reći kada šaljemo datoteke koristiti ćemo multer NPM paket. Paketa s istom svrhom ima više nego dovoljno da možete odabrati i neki drugi ako zaključite da vam više odgovara. Koji god koristili princip je isti, a tiče se multipart/form-data.
U mapi projekta instalirati ćemo novi paket pomoću naredbe $ npm install --save multer
Struktura projekta sada je bogatija za mapu multer:
1 2 3 4 5 6 7 8 |
| - KorisniciAPI/ | - node_modules/ | - body-parser/ | - express/ | - multer/ | - mysql/ | - server.js | - package.json |
Kao i package.json
1 2 3 4 5 6 |
"dependencies": { "body-parser": "^1.15.2", "express": "^4.14.0", "multer": "^1.2.1", "mysql": "^2.12.0" } |
Međutim, naš API još uvijek ne može koristiti multer, barem dok ga ne navedemo u server.js što ćemo sada i učiniti.
Server.js
U server.js dodajemo sljedeće:
1 2 |
var multer = require('multer') var upload = multer({ dest: '/uploads' }) |
Prva linija definira varijablu kojom pozivamo ranije dodani paket dok druga linija definira mapu u koju će se spremati datoteke koje budu dodane putem API-ja. Ta će se mapa stvoriti čim sljedeći put pokrenemo server.js, a nalazit će se unutar root mape KorisniciAPI.
Dodavanje korisnika i upload datoteka
API za dodavanje korisnika sada će dobiti neke nove mogućnosti.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
//Dodavanje korisnika apiRoutes.post('/dodajkorisnika', upload.any(),function (req, res, next) { console.log(req.body); console.log(req.files); pool.getConnection(function(err, connection) { if (err) { console.error("Dogodila se greška: " + err); } var korisnik = { k_ime: req.body.ime, k_prezime: req.body.prezime, k_slika: req.files[0].destination + "/" + req.files[0].filename, k_dokument: req.files[1].destination + "/" + req.files[1].filename }; connection.query('INSERT INTO korisnik SET ?', korisnik, function(err, rows) { if (err) { throw err; } else { res.json("Uspješno dodan korisnik!"); res.end(); } connection.release(); }); }); }) |
Sada ćemo pomoću Postmana dodati jednog korisnika, njegovu sliku i datoteku pa ćemo analizirati proces i rezultat.
Kao što se vidi iz gornje animacije, nakon što kliknemo na Send i pošaljemo ime, prezime, sliku i datoteku korisnika sve se zapiše u bazu podataka u obliku stringa.
console.log(req.body); i console.log(req.files); daju nam vrlo korisne informacije. Kao prvo možemo potvrditi da je sve što smo poslali putem Postmana i stiglo, a kao drugo možemo vidjeti od čega se sastoje naše datoteke i odlučiti u kojem ćemo ih obliku spremati u bazu podataka. U ovom slučaju koristimo destination i filename .
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
{ ime: 'Tomislav', prezime: 'Stanković' } [ { fieldname: 'slika', originalname: 'tomislav-stankovic.jpg', encoding: '7bit', mimetype: 'image/jpeg', destination: './uploads', filename: '6527f85adbde49f692efd52449764547', path: 'uploads\\6527f85adbde49f692efd52449764547', size: '15402' }, { fieldname: 'dokument', originalname: 'O-meni.docx', encoding: '7bit', mimetype: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', destination: './uploads', filename: 'ad6375db29809af74be25b2d8822f46f', path: 'uploads\\ad6375db29809af74be25b2d8822f46f', size: '12706' }] |
Sliku tj. datoteku na frontendu možemo prikazati u obliku: http://localhost:8080/destination/filename
I to je to što se dodavanja datoteka tiče. Nakon što smo se uvjerili da API radi možemo izraditi formu za unos sadržaja koju će koristiti korisnici.
Brisanje korisnika
Korisnika možemo obrisati korištenjem postojećeg API-ja. I kao što se vidi u prethodnom blog postu kada pošaljemo ID korisnika sve vezano uz njega briše se iz baze. Međutim ostaje jedan problem, a to su datoteke na disku koje nisu obrisane jer API-ju smo rekli da iz baze obriše samo korisnika s određenim ID-em, ali API neće i ne zna obrisati fizičke datoteke koje se nalaze na disku.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
apiRoutes.delete('/korisnik/:k_id', function(req, res, next){ pool.getConnection(function(err, connection) { if (err) { console.error("Dogodila se greška: " + err); } connection.query('delete from korisnik where k_id = ?', [req.params.k_id], function(err, rows) { if (err) { return next(err); } else { res.writeHead(200, { "Content-Type": "application/json" }); var result = { success: true } res.write(JSON.stringify(result)); res.end(); } }); }); }); |
Brisanje datoteka s diska
Kako bi to bilo moguće potrebno je koristiti Node File System (fs). Na vrhu server.js definirat ćemo varijablu var fs = require('fs');
API za brisanje korisnika sada izgleda ovako:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
apiRoutes.delete('/korisnik/:k_id/:k_slika/:k_dokument', function(req, res, next){ console.log(req.params); var slika = req.params.k_slika; var dokument = req.params.k_dokument; pool.getConnection(function(err, connection) { if (err) { console.error("Dogodila se greška: " + err); } connection.query('delete from korisnik where k_id = ?', [req.params.k_id], function(err, rows) { if (err) { return next(err); } else { fs.unlinkSync('./uploads/' + slika); fs.unlinkSync('./uploads/' + dokument); res.writeHead(200, { "Content-Type": "application/json" }); var result = { success: true } res.write(JSON.stringify(result)); res.end(); } }); }); }); |
Osim ID-ja korisnika sada šaljemo još i naziv slike tj. naziv dokumenta http://localhost:8080/api/korisnik/2/6527f85adbde49f692efd52449764547/ad6375db29809af74be25b2d8822f46f tako da smo ta dva nova parametra morali navesti i unutar API-ja '/korisnik/:k_id/:k_slika/:k_dokument'.
Kada pokrenemo API dobijemo console.log(req.params):
1 2 3 |
{ k_id: '2', k_slika: '6527f85adbde49f692efd52449764547', k_dokument: 'ad6375db29809af74be25b2d8822f46f' } |
i { "success": true }
Cijeli proces izgleda ovako:
Zaključak
Ovo je samo jedan od načina kako pomoću NodeJS-a napraviti upload i brisanje datoteka.
Posjetite GitHub i preuzmite projekt.